Mybatis批量保存 decimal类型数据精度丢失的问题

在一次工作中,使用了Mybatis的批量插入保存,语法如下:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

但是如果保存的字段中有一个decimal的类型,在多次测试中,你会发现这个decimal类型的数据最终保存到数据库的值,大多数情况下并不是你设置的值,而是被四舍五入了。

我们在上面的示例中加入一个salary 为 decimal类型的字段:

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio, salary) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio}, #{item.salary})
  </foreach>
</insert>

保存时,多条数据的salary分别赋值1990.5, 2026.76, 2596.31,最终入库后的结果为:1990.5, 2026.8, 2596.3

通过你会发现,小数位都被四舍五入保留一位了。

这说明Mybatis在批量保存decimal类型数据的时候,会以精度最小的decimal的数据来进行四舍五入。

解决方法:

对decimal的类型加入类型转换并指定精度:

cast(#{item.salary} as decimal(18,4))

如果插入语句中有多个decimal类型的数据,那么都需要这样处理,这样问题就解决啦。