背景:
表中增加了一个Json字段,以往对于json字段在实体类中都是给定个Object对象,然后在Mybatis操作的时候当作varchar操作,取出后在进行序列化成指定对象,不同于以往操作的情况,这次对象类型是确定的,所以计划把实体类中的字段写定为一个java对象,但是在更新的时候报错了:
思考和尝试:
- 根据堆栈,看来是java类型转JDBC类型的时候出的错,无法把一个String转为json,于是想到了mybatis的typehandler,
mybatis文档:
- 文档中提到了实现 org.apache.ibatis.type.TypeHandler 或者继承org.apache.ibatis.type.BaseTypeHandler,所以我直接使用了mybatisPlus中封装好了的:JackSonTypeHandler(点开是图)
, 然后把这个类加入到了mybatisPlus在实体类上的注解里面 - 尝试后还是不行(update报错,但是insert没问题),还是一样的报错,推测:使用mybatisPlus的update方法的时候 没有使用实体类上的typeHandler
- 去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,就可以了。