在数据库设计中,我们经常需要将复杂的Java对象(如Map、List、自定义POJO等)以JSON格式存储到数据库的某个字段中(如MySQL的JSON类型字段、PostgreSQL的jsonb字段等)。MyBatis-Plus 提供了 JSON类型处理器(TypeHandler) 来实现 Java 对象与数据库 JSON 字段之间的自动转换,避免手动编写序列化/反序列化代码。
![图片[1]_MyBatis-Plus JSON类型处理器详解_知途无界](https://zhituwujie.com/wp-content/uploads/2025/10/d2b5ca33bd20251014085703.png)
一、核心作用
JSON类型处理器的主要功能是:
在 Java 对象(如 Map<String, Object>、List<T>、自定义类等)与数据库的 JSON 字符串(或数据库原生 JSON 类型字段)之间自动完成序列化(Java→JSON字符串)和反序列化(JSON字符串→Java对象)。
二、MyBatis-Plus 内置的 JSON 类型处理器
MyBatis-Plus 基于 MyBatis 的类型处理器体系,默认提供了对常见 JSON 库(如 Jackson、Gson)的支持,常见的处理器包括:
| 处理器类 | 适用场景 | 依赖的 JSON 库 |
|---|---|---|
JacksonTypeHandler | 处理任意 Java 对象(如 POJO、Map、List)与 JSON 的转换 | Jackson (com.fasterxml.jackson) |
GsonTypeHandler | 同上,基于 Gson 实现 | Gson (com.google.code.gson) |
FastjsonTypeHandler(非官方,需自行实现) | 基于 Fastjson(不推荐,官方未内置) | Fastjson |
注意:MyBatis-Plus 默认没有直接内置所有 JSON 处理器,但 MyBatis 原生提供了
JacksonTypeHandler和GsonTypeHandler(需手动配置或依赖对应库)。MyBatis-Plus 在部分场景下会简化其使用方式。
三、使用步骤(以 Jackson 为例)
1. 添加依赖
确保项目中引入了 Jackson(MyBatis-Plus 默认依赖可能已包含,若无则手动添加):
<!-- MyBatis-Plus 依赖(通常已包含基础功能) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
<!-- Jackson 依赖(若项目中未引入) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version> <!-- 根据实际情况调整版本 -->
</dependency>
2. 定义实体类字段
假设我们有一个 User 实体,其中有一个字段 tags(类型为 List<String>)需要存储为数据库的 JSON 字段(如 MySQL 的 VARCHAR 或 JSON 类型):
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.List;
@TableName("user") // 对应数据库表名
public class User {
private Long id;
private String name;
// 关键:通过 @TableField 指定类型处理器
@TableField(typeHandler = com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler.class)
private List<String> tags; // 需要存储为 JSON 的字段
// getter/setter 省略...
}
注意:
- 如果使用 MyBatis 原生 的
JacksonTypeHandler,其完整类名是com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler(MyBatis-Plus 封装)或org.apache.ibatis.type.JacksonTypeHandler(MyBatis 原生,需确认版本)。- MyBatis-Plus 3.x+ 通常直接支持,无需显式指定
typeHandler(见下文简化用法)。
3. 简化用法(MyBatis-Plus 3.x+ 推荐)
MyBatis-Plus 3.x 及以上版本对 JSON 类型处理器进行了优化,如果数据库字段类型是 JSON(如 MySQL 的 JSON 类型)或字符串类型(如 VARCHAR),且字段类型是 Map、List、自定义 POJO 等,MyBatis-Plus 会自动使用内置的 JSON 处理器,无需手动指定 @TableField(typeHandler=...)。
示例(自动处理):
@TableName("user")
public class User {
private Long id;
private String name;
// 直接声明为 List<String>,MyBatis-Plus 会自动使用 JSON 处理器
private List<String> tags;
// 或者自定义 POJO
private Map<String, Object> extraInfo;
// getter/setter...
}
条件:
- 数据库字段类型需为 JSON 类型(如 MySQL 5.7+ 的
JSON类型、PostgreSQL 的jsonb) 或 字符串类型(如VARCHAR、TEXT)。 - MyBatis-Plus 会通过自动配置的
JacksonTypeHandler或GsonTypeHandler(根据项目依赖)完成转换。
4. 自定义 JSON 处理器(可选)
如果默认处理器不满足需求(如需要特殊序列化逻辑),可以自定义类型处理器并继承 BaseTypeHandler 或直接使用 Jackson/Gson API。
示例(自定义 Jackson 处理器):
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// 自定义类型处理器(处理 UserConfig 类与 JSON 的转换)
public class UserConfigTypeHandler extends BaseTypeHandler<UserConfig> {
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, UserConfig parameter, JdbcType jdbcType) throws SQLException {
try {
String json = objectMapper.writeValueAsString(parameter); // 序列化为 JSON 字符串
ps.setString(i, json);
} catch (Exception e) {
throw new SQLException("序列化 UserConfig 失败", e);
}
}
@Override
public UserConfig getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return parseJson(json); // 反序列化
}
// 其他重载方法(getNullableResult)类似...
private UserConfig parseJson(String json) throws SQLException {
if (json == null || json.isEmpty()) return null;
try {
return objectMapper.readValue(json, UserConfig.class);
} catch (Exception e) {
throw new SQLException("反序列化 UserConfig 失败", e);
}
}
}
然后在实体类字段上指定该处理器:
@TableField(typeHandler = UserConfigTypeHandler.class)
private UserConfig config; // 自定义 POJO 字段
四、数据库字段类型建议
- MySQL:推荐使用
JSON类型(MySQL 5.7+ 支持),或VARCHAR/TEXT(兼容旧版本)。 - PostgreSQL:推荐使用
jsonb类型(支持高效索引和查询)。 - Oracle:可使用
CLOB或VARCHAR2(存储 JSON 字符串)。
注意:如果数据库字段类型是
JSON(如 MySQL),数据库本身会校验 JSON 格式合法性;如果是字符串类型(如VARCHAR),需依赖应用层保证格式正确。
五、常见问题解决
1. 报错:找不到类型处理器
原因:未正确引入 Jackson/Gson 依赖,或未指定 typeHandler(旧版本可能需要手动指定)。
解决:
- 检查依赖:确保引入了
jackson-databind(或gson)。 - 显式指定处理器(MyBatis-Plus 3.x 之前可能需要):
@TableField(typeHandler = JacksonTypeHandler.class) private List<String> tags;
2. JSON 字段与 Java 类型不匹配
原因:数据库中的 JSON 数据结构与 Java 字段类型不一致(如数据库存的是 {"key":"value"},但 Java 字段声明为 List<String>)。
解决:确保 Java 字段类型与 JSON 数据结构匹配(如 JSON 是对象则用 Map<String, Object> 或自定义 POJO,是数组则用 List<T>)。
3. 序列化/反序列化失败
原因:Java 对象包含无法序列化的字段(如循环引用、非序列化类)。
解决:
- 使用
@JsonIgnore忽略敏感字段(Jackson)。 - 确保自定义 POJO 有无参构造方法(反序列化必需)。
六、总结
| 场景 | 解决方案 |
|---|---|
存储 List/Map/自定义 POJO 到 JSON 字段 | 直接声明字段类型(如 List<String>),MyBatis-Plus 3.x+ 自动处理;或手动指定 @TableField(typeHandler=JacksonTypeHandler.class) |
| 依赖库 | 引入 Jackson(jackson-databind)或 Gson(gson) |
| 数据库字段类型 | 推荐 JSON 类型(MySQL 5.7+/PostgreSQL jsonb),或 VARCHAR/TEXT |
| 自定义处理逻辑 | 继承 BaseTypeHandler 并实现序列化/反序列化方法 |
通过合理使用 JSON 类型处理器,可以极大简化复杂对象的数据库存储与查询,提升开发效率。

























暂无评论内容