文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

通过注解使用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;
    ...
    
    @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  (
    ...
    
    @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 类型:

定义:

@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;
    
    @TableField(value = "weight_list",typeHandler = WeightListTypeHandler.class,jdbcType = JdbcType.CLOB)
    private Map<String, List<WeightItem>> weightList;
    
    @TableField("status")
    private Integer status;
    
    @TableField("enable")
    private Integer enable;
    @TableField("create_time")
    private LocalDateTime createTime;
}

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯