在使用 MyBatis-Plus 进行业务开发时,我们时常需要把数据库中的 JSON 字段(比如字符串形式的数组)自动映射成 Java 中的 JSONArray 或 List 类型。
默认情况下,MyBatis-Plus 是不支持直接映射 JSON 类型的,这时候就需要借助:
- @TableField(typeHandler = …)
- 自定义或已有的 TypeHandler
- 配合 @TableName(autoResultMap = true) 才能正确生效!
真实场景举例
假设我们现在有一个旅游美食表 travel_cuisine,里面的字段 tag_list 是一个 JSON Array,用来存储标签 ID 列表,示例数据如下:
1 | [ "tag-101" , "tag-202" , "tag-333" ] |
我们希望在 Java 实体中使用如下形式自动映射:
1 2 | @TableField (typeHandler = JsonArrayTypeHandler. class ) private JSONArray tagList; |
接下来,教你一步步实现它。
一、@TableField + typeHandler 是什么?
@TableField 简介
@TableField 是 MyBatis-Plus 提供的字段级注解,用于说明字段与数据库的映射关系。
核心参数如下:
参数 | 说明 |
---|---|
value |
对应数据库字段名 |
exist |
字段是否存在于数据库表结构中 |
typeHandler |
字段转换处理器,用于复杂类型映射 |
typeHandler 作用
TypeHandler 是 MyBatis 中的一个重要机制,它负责Java 类型 和 JDBC 类型之间的转换。
你可以用它来处理:
- JSON ↔ Java 对象(如 JSONArray、Map、List)
- 逗号分隔字符串 ↔ List
- 枚举 ↔ 数据库存储值
简单来说,typeHandler 就是数据格式的桥梁!
二、@TableName(autoResultMap = true) 必须开启
默认情况下,MyBatis-Plus 的字段映射并不会使用 typeHandler,除非你在实体类加上:
1 | @TableName (value = "travel_cuisine" , autoResultMap = true ) |
autoResultMap 是什么?
这是告诉 MP:“请生成自定义的 ResultMap,否则我不支持 typeHandler 和复杂类型的转换!”
如果你忘记加这一项,typeHandler 是不会生效的!
三、实战代码:映射 JSON 字段为 JSONArray
1.数据库建表语句(简化版)
1 2 3 4 5 | CREATE TABLE travel_cuisine ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR (100), tag_list TEXT -- JSON Array 字符串 ); |
2.实体类配置
1 2 3 4 5 6 7 8 9 10 11 | @Data @TableName (value = "travel_cuisine" , autoResultMap = true ) public class TravelCuisineDO { private Long id; private String name; @TableField (typeHandler = JsonArrayTypeHandler. class ) private JSONArray tagList; } |
3.自定义 TypeHandler(基于 FastJSON)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class JsonArrayTypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(PreparedStatement ps, int i, JSONArray parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter.toJSONString()); } @Override public JSONArray getNullableResult(ResultSet rs, String columnName) throws SQLException { String result = rs.getString(columnName); return JSON.parseArray(result); } @Override public JSONArray getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String result = rs.getString(columnIndex); return JSON.parseArray(result); } @Override public JSONArray getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String result = cs.getString(columnIndex); return JSON.parseArray(result); } } |
提醒:这个 JsonArrayTypeHandler 使用的是 FastJSON,如需 Jackson,请更换转换逻辑。
四、常见问题排查指南
问题现象 | 解决方法或建议 |
---|---|
typeHandler 没有生效 | 检查实体类是否开启 autoResultMap = true |
报 JSON parse error | 确保数据库字段是真正的 JSON 格式 |
存储时字段为 null | 确认字段不是 transient,且未被忽略 |
想用 List 代替 JSONArray | 写一个 ListStringTypeHandler 即可 |
总结:三件事必须配套使用
配置项 | 说明 |
---|---|
@TableField(typeHandler = …) | 标记字段转换器 |
@TableName(autoResultMap = true) | 告诉 MP 启用复杂映射 |
自定义 TypeHandler | 将 JSON 字段与 Java 类型进行互转 |
到此这篇关于MyBatis-Plus实现优雅处理JSON字段映射的文章就介绍到这了,更多相关MyBatis-Plus处理JSON字段映射内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!