Mybatis-Plus自定义集合类型的类型处理器详解
程序员文章站
2022-06-10 10:38:31
目录1.配合xml文件2.手动注册两种方法,第一种很麻烦,对mp自带的插入操作有限制,后来改为更简洁的第二种方法1.配合xml文件typehandler/** * 描述:fastjson的集合对象类型...
两种方法,第一种很麻烦,对mp自带的插入操作有限制,后来改为更简洁的第二种方法
1.配合xml文件
typehandler
/** * 描述:fastjson的集合对象类型处理器,将mysql表中的json字段映射到实体类中的{@code list<?>}属性 * 对照mp自带的fastjsontypehandler,自带的类型处理器会把所有的{@code list<?>}都会解析为{@code list<jsonobject>}, * 这样在遍历其中对象时,调用对象属性的get、set方法就会发送类型转换jsonobject->?,这种情况转换错误。 * 该处理器必须配合xml文件使用,不然无法获取要解析的对象类型,同时不能配合mp自带的{@link com.baomidou.mybatisplus.annotation.tablefield} * 使用,默认情况下@tablefield会将javatype设置为字段的类型,如果是list<?>则type = list.class,无法明确其中的泛型,类型转换会变成jsonobject。 * 用法: * <pre>{@code * 1.实体类上使用注解@tablename(value = "表名", resultmap = "xml文件中的resultmap的id") * 2.xml文件中自定义resultmap并设置需要json转换的字段 * <result property="实体类属性名" column="表字段名" javatype="list中的对象全类名,例如list<email>,则javatype为email的全类名" typehandler="自定义处理器全类名"/> * 3.自定义方法上的用法 * @mapper * public interface demodao extends basemapper<demoentity> { * @select("select * from demo where demo_id = #{demoid}") * @resultmap(value = "xml文件中的resultmap的id") * list<demoentity> selectlistbydemoid(long demoid); * } * }</pre> */ @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 /** * json字段 */ 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; } /** * 注册类型处理器 * <pre>{@code * 1.list<demoinfo>类型处理器 * ... * }</pre> * * @param args incoming main method arguments * @throws exception on error */ @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对象 ...)导致报错
暂无优雅的解决方案,先做个记录 。以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
详解mybatis-plus使用@EnumValue注解的方式对枚举类型的处理
-
C# 泛型集合的自定义类型排序的实现
-
python 的集合类型详解
-
Mybatis-Plus自定义集合类型的类型处理器详解
-
iBATIS的自定义类型处理器TypeHandlerCallback
-
详解C#集合类型大盘点的图文代码
-
javascript自定义对象的三种类型方法代码详解
-
Java 集合框架 Arraylist的基本使用方法、Vector的特有方法、LinkedList的特有方法、在集合中删除重复自定义类型元素(重写equals方法)
-
javascript自定义对象的三种类型方法代码详解
-
详解mybatis-plus使用@EnumValue注解的方式对枚举类型的处理