Mybaits/Mybatis-Plus JSON字段类型转换
注意:
框架不支持泛型转换 例如:List 的泛型转换,默认查找第一个List类型的TypeHandler
一、Mybatis
- 实现BaseTypeHandler抽象类型进行类型转换,可以去copy一下Mybatis-Plus下com.baomidou.mybatisplus.extension.handlers包中的几个通用Handler,或者自己实现BaseTypeHandler
-
使用Handler,result标签typeHandler字段设置自定义Handler完整包路径 eg:
<result property="attachments" column="attachments" typeHandler="com.business.handler.AttachmentHandler"/>
二、Mybatis-Plus
- 简单类型转换com.baomidou.mybatisplus.extension.handlers下的几个handler选一个就ok,如下:
@TableField(typeHandler = JacksonTypeHandler.class)
private Demo demo;
三、泛型处理
由于不支持泛型,我们曲线救国,下面我们以List 为例子
-
继承ArrayList,封装我们自己的List
import java.util.ArrayList; public class StringList extends ArrayList<String> { } -
封装对应的Handler处理 自定义泛型注解 配合Handler处理泛型解析问题,value -> 泛型,List value -> String.class
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MappedTypeGeneric { Class<?> value(); }抽象类型Handler List处理
import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler; import org.apache.ibatis.type.MappedTypes; import java.lang.reflect.Type; import java.util.ArrayList; public abstract class AbstractListJsonTypeHandler<T extends ArrayList<?>> extends AbstractJsonTypeHandler<T> { @Override protected T parse(String json) { try { if (json == null || json.trim().isEmpty()) { return createEmptyInstance(); } T result = createEmptyInstance(); result.addAll(JSON.parseArray(json, getElementType())); return result; } catch (Exception e) { return null; } } @Override protected String toJson(T obj) { if (obj != null) { return JSON.toJSONString(obj); } return null; } /** * 创建空的集合实例 */ protected T createEmptyInstance() { try { Class<?> listClass = getClass() .getAnnotation(MappedTypes.class).value()[0]; return (T) listClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new IllegalStateException("Failed to create list instance", e); } } /** * 获取集合元素类型 */ protected Type getElementType(){ //获取注解值 MappedTypeGeneric return getClass().getAnnotation(MappedTypeGeneric.class).value(); } }
createEmptyInstance也可以写成abstract抽象方法交给子类实现
StringListJsonTypeHandler 处理List 转换
import com.hm.pms.common.mybatis.lang.StringList;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
@MappedTypes(StringList.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypeGeneric(String.class)
public class StringListJsonTypeHandler extends AbstractListJsonTypeHandler<StringList>{
@Override
protected StringList createEmptyInstance() {
return new StringList();
}
}
使用
@TableField(typeHandler = StringListJsonTypeHandler.class)
private List<String> stringList;
这样子,我们就有了一个能处理所有List泛型的模版
第一步:自定义List继承ArrayList
第二步:自定义TypeHandler继承AbstractListJsonTypeHandler,添加@MappedTypeGeneric解析类型
第三步:使用TypeHandler进行转换
Spring开启mybatis-plus 自定义类型转换配置,扫描包下的handler
mybatis-plus:
type-handlers-package: com.business.handler