作者:William Dawson | 更新日期:2025-04-21
标签:MyBatis-Plus、JSON、TypeHandler、@TableField、@TableName、FastJSON
在使用 MyBatis-Plus 进行业务开发时,我们时常需要把数据库中的 JSON 字段(比如字符串形式的数组)自动映射成 Java 中的 JSONArray
或 List
类型。
默认情况下,MyBatis-Plus 是不支持直接映射 JSON 类型的,这时候就需要借助:
✅ @TableField(typeHandler = ...)
✅ 自定义或已有的 TypeHandler
✅ 配合 @TableName(autoResultMap = true)
才能正确生效!
假设我们现在有一个旅游美食表 travel_cuisine
,里面的字段 tag_list
是一个 JSON Array
,用来存储标签 ID 列表,示例数据如下:
["tag-101", "tag-202", "tag-333"]
我们希望在 Java 实体中使用如下形式自动映射:
@TableField(typeHandler = JsonArrayTypeHandler.class)
private JSONArray tagList;
接下来,教你一步步实现它。
@TableField
是 MyBatis-Plus 提供的字段级注解,用于说明字段与数据库的映射关系。
核心参数如下:
参数 | 说明 |
---|---|
value |
对应数据库字段名 |
exist |
字段是否存在于数据库表结构中 |
typeHandler |
字段转换处理器,用于复杂类型映射 |
TypeHandler
是 MyBatis 中的一个重要机制,它负责Java 类型 和 JDBC 类型之间的转换。
你可以用它来处理:
简单来说,typeHandler
就是数据格式的桥梁!
默认情况下,MyBatis-Plus 的字段映射并不会使用 typeHandler
,除非你在实体类加上:
@TableName(value = "travel_cuisine", autoResultMap = true)
这是告诉 MP:“请生成自定义的 ResultMap,否则我不支持 typeHandler 和复杂类型的转换!”
如果你忘记加这一项,typeHandler 是不会生效的!
CREATE TABLE travel_cuisine (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
tag_list TEXT -- JSON Array 字符串
);
@Data
@TableName(value = "travel_cuisine", autoResultMap = true)
public class TravelCuisineDO {
private Long id;
private String name;
@TableField(typeHandler = JsonArrayTypeHandler.class)
private JSONArray tagList;
}
public class JsonArrayTypeHandler extends BaseTypeHandler<JSONArray> {
@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 字段的正确姿势 ✅
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注,一起交流更多 Java 技术经验!
关注我|获取更多干货:
Java 全栈|项目实战|面试题整理|源码精讲