信息发布→ 登录 注册 退出

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

发布时间:2026-01-11

点击量:
目录
  • 通过注解使用TypeHandler
    • 官方示例
    • Kotlin案例
  • 自定义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;
    }

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

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!