两种方法,第一种很麻烦,对mp自带的插入操作有限制,后来改为更简洁的第二种方法
1.配合xml文件
TypeHandler
@Slf4j
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class FastJsonArrayTypeHandler extends AbstractJsonTypeHandler<List<?>> {
private Class<?> type;
public FastJsonArrayTypeHandler(Class<?> type) {
if (log.isTraceEnabled()) {
log.trace("FastjsonTypeHandler(" + type + ")");
}
Assert.notNull(type, "Type argument cannot be null");
this.type = type;
}
@Override
protected List<?> parse(String json) {
return JSON.parseArray(json, type);// 注意不要使用parseObject方法
}
@Override
protected String toJson(List<?> obj) {
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
}
}
xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="a.b.dao.DemoDao">
<resultMap type="a.b.entity.DemoEntity" id="demoMap">
<result property="DemoInfo" column="demo_info" javaType="a.b.xx.DiseaseInfo" typeHandler="a.b.handler.FastJsonArrayTypeHandler"/>
</resultMap>
</mapper>
Dao
@Mapper
public interface DemoDao extends BaseMapper<DemoEntity> {
@Select("select * from demo where demo_id = #{demoId}")
@ResultMap(value = "demoMap")
List<DemoEntity> selectListByPlanId(Long demoId);
}
Entity
@Data
@TableName(value = "demo", resultMap = "demoMap")
public class DemoEntity implements Serializable {
private static final long serialVersionUID = -1L;
@TableId
private Long id;
private Long demoId
private List<DemoInfo> demoInfo;
}
2.手动注册
TypeHandler
@Slf4j
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class FastJsonArrayTypeHandler<T> extends AbstractJsonTypeHandler<Object> {
private TypeReference<List<T>> type;
public FastJsonArrayTypeHandler(TypeReference<List<T>> type) {
this.type = type;
}
@Override
protected Object parse(String json) {
return JSON.parseObject(json, type);
}
@Override
protected String toJson(Object obj) {
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
}
}
初始化,剩下的bean和dao都不需要额外配置
@Component
public class InitConfig implements CommandLineRunner {
public static final com.alibaba.fastjson.TypeReference<List<DemoInfo>> F_DEMO_INFO = new com.alibaba.fastjson.TypeReference<List<DemoInfo>>() {
};
public static final TypeReference<List<DemoInfo>> M_DEMO_INFO = new TypeReference<List<DemoInfo>>() {
};
// mp自动装配时注入的factory,可用于获取mybatis的配置属性,这里用来获取类型处理器的注册器
private final SqlSessionFactory factory;
public InitConfig(SqlSessionFactory factory) {
this.factory = factory;
}
@SuppressWarnings("all")
@Override
public void run(String... args) throws Exception {
TypeHandlerRegistry typeHandlerRegistry = factory.getConfiguration().getTypeHandlerRegistry();
typeHandlerRegistry.register(M_DEMO_INFO, new FastJsonArrayTypeHandler(F_DEMO_INFO));
}
}
目前方法二存在的缺陷:虽然新增、查询不存在问题,执行MP自带的更新操作时,parameterMap参数类型都是Object,不会经过自定义的TypeHandler处理,最后会把json对象直接set进去(update demo ..., demo_info = JSON对象 ...)导致报错
暂无优雅的解决方案,先做个记录 。以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。