MyBatis-Plus如何通过注解使用TypeHandler

 更新时间:2022年01月13日 14:21:13   作者:幻想千秋  
这篇文章主要介绍了MyBatis-Plus如何通过注解使用TypeHandler,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

通过注解使用TypeHandler

在使用MyBatis时,我们与数据表中字段映射的java中的bean的属性字段,往往包含了自定义复杂类型,比如一个varchar保存的json字符串映射到的java字段是Person类型的时候,就需要用到 “字段类型处理器了”,也就是TypeHandler.

使用MyBatis的TypeHandler的时候,自定义实现起来还是比较麻烦,需要统一配置,自动识别java字段类型,然后匹配了才处理。

这样在开发的时候并不好控制,而且不是很直观。

在新版本的MyBatis-Plus中提供了一种新的配置 “字段处理器” 的方法,通过在javaBean中加入对应的注解即可实现。

下面我们先看一下MyBatis-Plus官方文档中的使用说明:

官方示例

类型处理器,用于 JavaType 与 JdbcType 之间的转换,用于 PreparedStatement 设置参数值和从 ResultSet 或 CallableStatement 中取出一个值,本文讲解 mybaits-plus 内置常用类型处理器如何通过TableField注解快速注入到 mybatis 容器中。

示例工程:

👉 mybatis-plus-sample-typehandlerJSON 字段类型 

@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
    private Long id;
    ...
    /**
     * 注意!! 必须开启映射注解
     *
     * @TableName(autoResultMap = true)
     *
     * 以下两种类型处理器,二选一 也可以同时存在
     *
     * 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    // @TableField(typeHandler = FastjsonTypeHandler.class)
    private OtherInfo otherInfo;
}

该注解对应了 XML 中写法为

<result column="other_info" jdbcType="VARCHAR" property="otherInfo" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />

下面我们参照官方给出的案例,用kotlin实现一个具体的:

Kotlin案例

首先是kotlin实体类:

@TableName(autoResultMap = true)
data class Policy  (
    ...
    /**
     * 策略内容,json格式,规则参考文档
     */
    @TableField(typeHandler = PolicyBodyTypeHandler::class)
    var content: PolicyBody? = null,
    ...
)

然后是对应TypeHandler的实现,主要就是json序列化规则,因为我们再数据库存的就是json字符串。

class PolicyBodyTypeHandler : BaseTypeHandler<PolicyBody>() {
    override fun getNullableResult(p0: ResultSet?, p1: String?): PolicyBody? {
        val result = p0?.getString(p1) ?: return null
        return JSON.parseObject(result, PolicyBody::class.java)
    }
    override fun getNullableResult(p0: ResultSet?, p1: Int): PolicyBody? {
        val result = p0?.getString(p1) ?: return null
        return JSON.parseObject(result, PolicyBody::class.java)
    }
    override fun getNullableResult(p0: CallableStatement?, p1: Int): PolicyBody? {
        val result = p0?.getString(p1) ?: return null
        return JSON.parseObject(result, PolicyBody::class.java)
    }
    override fun setNonNullParameter(statement: PreparedStatement?, index: Int, javaObj: PolicyBody?, jdbcType: JdbcType?) {
        statement?.setString(index, JSON.toJSONString(javaObj))
    }
}

下面是xml中的使用:

<!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.inooy.write.ucenter.entity.Policy">
        <id column="id" property="id" />
        <result column="code" property="code" />
        <result column="name" property="name" />
        <result column="description" property="description" />
        <result column="content" property="content" typeHandler="com.inooy.write.ucenter.policy.PolicyBodyTypeHandler"/>
        <result column="deleted" property="deleted" />
        <result column="createTime" property="createTime" />
        <result column="updateTime" property="updateTime" />
        <result column="version" property="version" />
    </resultMap>

自定义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;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot Mybatis批量插入Oracle数据库数据

    SpringBoot Mybatis批量插入Oracle数据库数据

    这篇文章主要介绍了SpringBoot Mybatis批量插入Oracle数据库数据,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • 简单了解spring bean的循环引用

    简单了解spring bean的循环引用

    这篇文章主要介绍了简单了解spring bean的循环引用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 详解怎么用Java的super关键字

    详解怎么用Java的super关键字

    今天带大家学习Java中super关键字是怎么用的,文中有非常详细的介绍,对正在学习的小伙伴们很有帮助,需要的朋友可以参考下
    2021-06-06
  • java @Value(

    java @Value(

    这篇文章主要介绍了java @Value("${}")获取不到配置文件中值的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Java 选择排序、插入排序、希尔算法实例详解

    Java 选择排序、插入排序、希尔算法实例详解

    这篇文章主要介绍了Java 选择排序、插入排序、希尔算法实例详解,需要的朋友可以参考下
    2017-05-05
  • Java编程实现数组转成list及list转数组的方法

    Java编程实现数组转成list及list转数组的方法

    这篇文章主要介绍了Java编程实现数组转成list及list转数组的方法,结合实例形式较为详细的总结分析了java实现数组与list之间相互转换的操作技巧,需要的朋友可以参考下
    2017-09-09
  • 详解 Java Maximum redirects (100) exceeded

    详解 Java Maximum redirects (100) exceeded

    这篇文章主要介绍了详解 Java Maximum redirects (100) exceeded的相关资料,需要的朋友可以参考下
    2017-05-05
  • Kotlin基本类型自动装箱出现问题解决办法

    Kotlin基本类型自动装箱出现问题解决办法

    这篇文章主要介绍了Kotlin基本类型自动装箱出现问题解决办法的相关资料,希望通过本文能帮助到大家,让大家遇到这样的问题顺利解决,需要的朋友可以参考下
    2017-10-10
  • Java中如何利用Set判断List集合中是否有重复元素

    Java中如何利用Set判断List集合中是否有重复元素

    在开发工作中,我们有时需要去判断List集合中是否含有重复的元素,这时候我们不需要找出重复的元素,我们只需要返回一个 Boolean 类型就可以了,下面通过本文给大家介绍Java中利用Set判断List集合中是否有重复元素,需要的朋友可以参考下
    2023-05-05
  • spring boot 使用 @Scheduled 注解和 TaskScheduler 接口实现定时任务

    spring boot 使用 @Scheduled 注解和 TaskScheduler 接口实现定时任务

    这篇文章主要介绍了spring boot 使用 @Scheduled 注解和 TaskScheduler 接口实现定时任务,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06

最新评论