背景:参与开发的系统A要与系统B交互,系统B使用的是SQLServer数据库,为了快速开发当时想采用dblink实现,但为了安全性起见,还是采用接口实现,接口的客户端和服务端都是自己写,采用的Mybatis操作数据库,批量插入。
问题:A系统的数据同步至B系统时,小数的精度丢失了。
排查:断点跟踪了接口客户端、服务端的数据,到插入SQLServer数据库之前数字数据都是正确的,而且字段的数据类型为Decimal(14,5),后来找同事求助,同事百度查说,应该是mybatis批量插入导致的。
解决方案:
在批量插入SQL时,cast(#{item.amount,jdbcType=DECIMAL} as decimal(14,5)) ,如:
insert into JY_GCHANGE_MX (PK, HZID, MXID, GCODE, BATCHCODE, BATCHNO, PRODUCEDATE, AMOUNT, STOCKNAME ) VALUES ( #{item.pk,jdbcType=INTEGER},#{item.hzid,jdbcType=INTEGER},#{item.mxid,jdbcType=INTEGER},#{item.goodscode,jdbcType=VARCHAR}, #{item.batchcode,jdbcType=VARCHAR}, #{item.batchno,jdbcType=VARCHAR},#{item.producedate,jdbcType=DATE},cast(#{item.amount,jdbcType=DECIMAL} as decimal(14,5)),#{item.stockname,jdbcType=NVARCHAR} )
而后在网上还查到另一种解决方案(未试):
公司最近的项目用的是sqlserver数据库,maven依赖为:
com.microsoft.sqlserver mssql-jdbc 6.4.0.jre7
执行批量插入语句时,原本小数点后有三位小数,检查数据库发现小数点后的数字全变为0了,这让朕百思不得其解啊!于是乎检查mapper.xml文件发现没问题,debug跑了一下,发现执行流程没问题,到执行语句前,小数点后数字都还是存在的,但是执行语句后,数据库里数据变成了.000,最后把sqlserver驱动换成了sqljdbc4,重新执行代码后,数据库里的数据一切正常.下面是sqlserver4的maven依赖
com.microsoft.sqlserver sqljdbc4
不过要使用sqljdbc4必须先把jar包先安装到本地仓库才可使用,因为中央仓库没有这玩意.