Month: February 2023

MyBatis批量更新问题

今天碰到个奇怪的问题,MyBatis批量更新数据时,在MySQL可以正常执行,但在PostgreSQL数据库上,有时会出现错误。 更新的sql语句如下,用户名称如果不为null才更新,age和sex无论是否为null都会更新: 错误提示大概如下: 这里如果只是简单的更新出错,那么倒没有什么可说。奇怪的地方在于,在PostgreSQL数据库批量更新时,如果列表中任意一条记录age和sex都有值,仍然可以正常更新,但如果列表中所有记录的age和sex都为null,那么就会出现上面的错误。出现错误的原因估计是因为列表所有元素两个字段值都为null时,更新代码不能判断要更新字段值的类型,转换成text类型进行处理了。 解决的方法很简单,就是在更新字段上面指明类型,即修改下面两处即可: when id = #{item.id} then #{item.age, jdbcType=INTEGER} when id = #{item.id} then #{item.sex, jdbcType=SMALLINT} 猜测问题可能是在MyBatis框架?既然已经参数类型parameterType=UserInfo,那么属于该类的字段应该能够默认添加类型才对? 问题出现原因: 其他备忘: 突然想起当时为啥使用sql来进行更新了。 这个问题是在项目中碰到的,之所以使用mapper写sql进行更新还是有原因的。一开始的写法不仅简单,而且还不会出现这个问题,就是在实体中使用注解标识,为null也进行更新,例如: @TableField(value = “age”, updateStrategy = FieldStrategy.IGNORED) 但是有人觉得项目是他接手的,就得按照他的规则来,然后说使用mybatis自动生成的就不能修改,如果有修改,代码自动生成后会毫不犹豫覆盖。当时代码一开始是我生成,后面他有修改过,在做新需求时,发现表都重建了,新增时会自动生成默认值的status字段、创建日期,更新日期字段都变成无默认值了,实体类也被直接覆盖了,根本不看原来的代码是怎样的,实体注解标识id为自动生成、以及设置字段更新策略的注解都没了。 @TableId(value = “id”, type = IdType.AUTO) @TableField(updateStrategy = FieldStrategy.IGNORED) 当时也很傻,觉得跟这种人打交道很烦,就问了下他数据库表字段定义是不是有变更了,也没有怎么说他就默默的在生成器添加了设置id自动生成的注解重新生成,新增对象时也手动设置了状态、创建时间和更新时间,还重新使用sql写了批量更新。