用Java对象类型更新Json字段时,和TypeHandler的两三事

背景:

表中增加了一个Json字段,以往对于json字段在实体类中都是给定个Object对象,然后在Mybatis操作的时候当作varchar操作,取出后在进行序列化成指定对象,不同于以往操作的情况,这次对象类型是确定的,所以计划把实体类中的字段写定为一个java对象,但是在更新的时候报错了:
image.png

思考和尝试:

  1. 根据堆栈,看来是java类型转JDBC类型的时候出的错,无法把一个String转为json,于是想到了mybatis的typehandler
    mybatis文档:
    image.png
  2. 文档中提到了实现 org.apache.ibatis.type.TypeHandler 或者继承org.apache.ibatis.type.BaseTypeHandler,所以我直接使用了mybatisPlus中封装好了的:JackSonTypeHandler(点开是图)
    , 然后把这个类加入到了mybatisPlus在实体类上的注解里面image.png
  3. 尝试后还是不行(update报错,但是insert没问题),还是一样的报错,推测:使用mybatisPlus的update方法的时候 没有使用实体类上的typeHandler
  4. 去mybatisPlus的issue中寻找答案,发现了个情况十分类似的问题:https://github.com/baomidou/mybatis-plus/issues/794
    issue中作者提到:如果是传入对象 使用“对象.属性”的方式 或者wrapper的方式, 都不会使用typeHandler,所以如果mapper 中接口参数是表的实体的话,就不能使用传统的方式,可以使用注解的方式解决

    @Update("update biz_task set TASK_DATA = #{task.taskData,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} where ID = #{task.id}")  
    int updateTaskDataById(@Param("task") TaskVO task)

    然后在xml中修改resultType ,也加上对应的typeHandler ,防止查询出问题。文档:https://mp.baomidou.com/guide/typehandler.html 问题解决。

    结论:

    实体类上加入注解,指定typeHandler,并且加入xml中,如果需要更新Json字段时候 传入java对象且使用typeHandler, 不能使用mybatisPlus 自己的update方法 因为本质上也是是用的“对象.属性”的方式,需要自己写sql 并且在el表达式部分指定typeHandler,就可以了。

发表回复

蒙ICP备2022000577号-1