自定义序列化:MyBatis-Plus处理复杂对象序列化和反序列化
痛点:复杂对象存储的困境
在日常开发中,你是否遇到过这样的场景:需要将复杂的Java对象(如嵌套对象、集合、枚举等)存储到数据库的单个字段中?传统做法需要手动进行JSON序列化和反序列化,代码冗余且容易出错。
MyBatis-Plus提供了强大的自定义序列化机制,通过TypeHandler(类型处理器)完美解决了这个问题。本文将深入解析MyBatis-Plus的序列化处理机制,帮助你掌握复杂对象存储的最佳实践。
核心架构:IJsonTypeHandler接口体系
MyBatis-Plus的序列化处理基于IJsonTypeHandler接口,这是一个专门为JSON序列化设计的类型处理器接口。
// IJsonTypeHandler接口定义
public interface IJsonTypeHandler<T> {
// 反序列化json
T parse(String json);
// 序列化json
String toJson(T obj);
}
架构流程图
内置JSON类型处理器对比
MyBatis-Plus提供了多种开箱即用的JSON类型处理器,满足不同项目的需求:
| 处理器类型 | 依赖库 | 性能特点 | 适用场景 |
|---|---|---|---|
| JacksonTypeHandler | Jackson | 高性能,功能丰富 | 企业级应用首选 |
| GsonTypeHandler | Gson | 轻量级,API简洁 | 简单JSON处理 |
| FastjsonTypeHandler | Fastjson | 速度快,兼容性好 | 高并发场景 |
| Fastjson2TypeHandler | Fastjson2 | 性能极致优化 | 极致性能要求 |
实战:自定义复杂对象序列化
1. 定义复杂数据模型
首先创建一个包含嵌套结构的复杂对象:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserProfile implements Serializable {
private Long userId;
private String username;
private List<String> roles; // 列表类型
private Map<String, Object> preferences; // Map类型
private Address address; // 嵌套对象
@Data
public static class Address {
private String province;
private String city;
private String detail;
}
}
2. 实体类配置TypeHandler
在实体类中使用@TableField注解指定类型处理器:
@Data
@TableName(value = "user_table", autoResultMap = true)
public class UserEntity {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
@TableField(typeHandler = JacksonTypeHandler.class)
private UserProfile profile; // 复杂对象字段
}
3. XML映射配置
在MyBatis的XML映射文件中配置resultMap:
<resultMap id="userResultMap" type="UserEntity">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="profile" column="profile"
javaType="com.example.UserProfile"
typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
</resultMap>
4. 自定义TypeHandler实现
如果需要特殊处理,可以自定义TypeHandler:
public class CustomJsonTypeHandler extends AbstractJsonTypeHandler<UserProfile> {
private static final ObjectMapper objectMapper = new ObjectMapper();
public CustomJsonTypeHandler(Class<?> type) {
super(type);
}
@Override
public UserProfile parse(String json) {
try {
// 自定义反序列化逻辑
return objectMapper.readValue(json, UserProfile.class);
} catch (Exception e) {
throw new RuntimeException("JSON解析失败", e);
}
}
@Override
public String toJson(UserProfile obj) {
try {
// 自定义序列化逻辑
return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException("JSON序列化失败", e);
}
}
}
序列化过程详解
存储过程(序列化)
查询过程(反序列化)
高级特性与最佳实践
1. 泛型支持
MyBatis-Plus支持泛型类型的序列化:
// 处理泛型集合
public class ListTypeHandler extends AbstractJsonTypeHandler<List<String>> {
public ListTypeHandler(Class<?> type) {
super(type);
}
@Override
public List<String> parse(String json) {
return objectMapper.readValue(json,
objectMapper.getTypeFactory().constructCollectionType(List.class, String.class));
}
}
2. 字段级配置
支持基于字段的特定配置:
public class FieldAwareTypeHandler extends AbstractJsonTypeHandler<Object> {
private final Field field;
public FieldAwareTypeHandler(Class<?> type, Field field) {
super(type, field);
this.field = field;
}
@Override
public Object parse(String json) {
// 根据字段信息进行特殊处理
if (field.getName().equals("sensitiveData")) {
return decrypt(json);
}
return objectMapper.readValue(json, type);
}
}
3. 性能优化建议
| 优化策略 | 实施方法 | 效果预估 |
|---|---|---|
| 对象复用 | 使用静态ObjectMapper实例 | 减少30%内存分配 |
| 缓存机制 | 缓存解析结果 | 提升50%查询性能 |
| 懒加载 | 按需序列化 | 减少不必要的CPU消耗 |
常见问题解决方案
问题1:循环引用处理
// 配置ObjectMapper解决循环引用
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
问题2:自定义日期格式
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
问题3:空值处理
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
测试验证
编写完整的测试用例确保序列化正确性:
@Test
public void testCustomSerialization() {
UserProfile profile = new UserProfile();
profile.setUserId(1L);
profile.setUsername("testUser");
profile.setRoles(Arrays.asList("admin", "user"));
// 测试序列化
CustomJsonTypeHandler handler = new CustomJsonTypeHandler(UserProfile.class);
String json = handler.toJson(profile);
assertNotNull(json);
// 测试反序列化
UserProfile parsed = handler.parse(json);
assertEquals(profile.getUserId(), parsed.getUserId());
assertEquals(profile.getRoles(), parsed.getRoles());
}
总结与展望
MyBatis-Plus的自定义序列化机制为处理复杂对象提供了完整的解决方案。通过IJsonTypeHandler接口体系,开发者可以:
- 灵活选择:根据项目需求选择合适的JSON处理库
- 自定义扩展:实现特定业务逻辑的序列化规则
- 性能优化:通过缓存和对象复用提升处理效率
- 类型安全:完整的泛型支持确保类型安全
未来,MyBatis-Plus将继续优化序列化性能,支持更多数据格式,并提供更细粒度的控制选项,帮助开发者更好地处理复杂数据存储场景。
掌握MyBatis-Plus的自定义序列化能力,让你在复杂业务场景下游刃有余,大幅提升开发效率和系统性能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



