MybatisPlus如何自定义TypeHandler映射JSON类型为List
程序员文章站
2022-06-17 21:26:19
目录自定义typehandler映射json类型为list1. 实体类2. listtypehandler3. reportuserlisttypehandler4. java 泛型自定义typeha...
自定义typehandler映射json类型为list
1. 实体类
这里只展示需要映射的字段,分别在所需映射的字段和实体类上添加注解。
@data @tablename(value = "report", autoresultmap = true) public class report { private static final long serialversionuid = 1l; @apimodelproperty("id") @tableid(value = "id", type = idtype.auto) private integer id; @apimodelproperty("报名信息") @tablefield(typehandler = reportuserlisttypehandler.class) private list<reportuser> reportinfo; }
2. listtypehandler
提供一个 jsonarray 转换为 java list集合的处理器
import cn.hutool.core.collection.collutil; import cn.hutool.core.util.strutil; import com.alibaba.fastjson.json; import com.alibaba.fastjson.typereference; import org.apache.ibatis.type.basetypehandler; import org.apache.ibatis.type.jdbctype; import org.apache.ibatis.type.mappedjdbctypes; import org.apache.ibatis.type.mappedtypes; import java.sql.callablestatement; import java.sql.preparedstatement; import java.sql.resultset; import java.sql.sqlexception; import java.util.arraylist; import java.util.list; @mappedjdbctypes(jdbctype.varbinary) @mappedtypes({list.class}) public abstract class listtypehandler<t> extends basetypehandler<list<t>> { @override public void setnonnullparameter(preparedstatement ps, int i, list<t> parameter, jdbctype jdbctype) throws sqlexception { string content = collutil.isempty(parameter) ? null : json.tojsonstring(parameter); ps.setstring(i, content); } @override public list<t> getnullableresult(resultset rs, string columnname) throws sqlexception { return this.getlistbyjsonarraystring(rs.getstring(columnname)); } @override public list<t> getnullableresult(resultset rs, int columnindex) throws sqlexception { return this.getlistbyjsonarraystring(rs.getstring(columnindex)); } @override public list<t> getnullableresult(callablestatement cs, int columnindex) throws sqlexception { return this.getlistbyjsonarraystring(cs.getstring(columnindex)); } private list<t> getlistbyjsonarraystring(string content) { return strutil.isblank(content) ? new arraylist<>() : json.parseobject(content, this.specifictype()); } /** * 具体类型,由子类提供 * * @return 具体类型 */ protected abstract typereference<list<t>> specifictype(); }
3. reportuserlisttypehandler
由具体的子类提供list集合泛型类型
import com.alibaba.fastjson.typereference; import com.hanku.business.model.reportuser; import java.util.list; public class reportuserlisttypehandler extends listtypehandler<reportuser> { @override protected typereference<list<reportuser>> specifictype() { return new typereference<list<reportuser>>() { }; } }
4. java 泛型
如果在 listtypehandler 类中直接提供 typereference<list<t>> 这种类型,那就等效于typereference<list<object>> 这种类型,后续 fastjson 在转换时无法确定具体的 java 类型,转换后的类型最终就会是 list<jsonobject> ;同理,如果使用 jackson 作为 json 转换工具,不确定具体类型时,最总会被转换为linkedhashmap 类型,都需要再使用 typereference 来转换一次。
自定义typehandler的使用笔记
可通过自定义的typehandler实现某个属性在插入数据库以及查询时的自动转换,本例中是要将map类型的属性转化成clob,然后存入数据库。由于是复杂的map,mp自带的json转换器会丢失部分信息。
类型转换器还可以通过注解配置 java类型和jdbc类型
-
@mappedtypes
:注解配置 java 类型 -
@mappedjdbctypes
:注解配置 jdbc 类型
定义
@slf4j @mappedtypes({object.class}) @mappedjdbctypes(jdbctype.varchar) public class weightlisttypehandler extends abstractjsontypehandler<object> { private static gson gson = new gson(); private final class<?> type; public weightlisttypehandler(class<?> type) { if (log.istraceenabled()) { log.trace("weightlisttypehandler(" + type + ")"); } assert.notnull(type, "type argument cannot be null"); this.type = type; } @override protected object parse(string json) { type type1 = new typetoken<map<string, list<weightitem>>>(){}.gettype(); return gson.fromjson(json, type1); } @override protected string tojson(object obj) { return gson.tojson(obj); } public static void setgson(gson gson) { assert.notnull(gson, "gson should not be null"); weightlisttypehandler.gson = gson; } }
使用
注意@tablename 注解 autoresultmap 属性
@data @noargsconstructor @tablename(value = "mix_target",autoresultmap = true) public class mixtarget extends model<mixtarget> { @tableid(value = "id", type = idtype.auto) private long id; /** *指标描述 */ @tablefield("description") private string description; /** * 指标名 */ @tablefield("name") private string name; /** * 对应属性名 */ @tablefield("property_name") private string propertyname; /** * 起始点类型 */ @tablefield("source_type") private string sourcetype; /** * 属性对应权值列表 * key 属性名 value指定条件下的权值 */ @tablefield(value = "weight_list",typehandler = weightlisttypehandler.class,jdbctype = jdbctype.clob) private map<string, list<weightitem>> weightlist; /** * 运行状态 * 0 新建未运行 * 1 运行中 * 2 已运行 成功 * 3 已运行 失败 */ @tablefield("status") private integer status; /** * 是否可用 * 1 true * 0 false */ @tablefield("enable") private integer enable; @tablefield("create_time") private localdatetime createtime; }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。