开心一刻
中午和哥们一起喝茶
哥们说道:晚上喝酒去啊
我:不去,我女朋友过生日
哥们瞪大眼睛看着我:你有病吧,充气的过什么生日
我生气到:有特么生产日期的好吧
需求背景
系统对接了外部系统,调用外部系统的接口需要付费,一个接口一次调用付费 0.03 元
同一个月内,同一个接口最高付费 25 元
统计每个月的付费情况
需求清楚了不?不清楚? 给大家举个案例
这下明白了吧
明白了需求,相信大家都会觉得很简单,不就是一个分组汇总吗?
客官说的对,但生活总会给我们一点 surprise
我们慢慢往下看
环境准备
SQL Server 版本: SQL Server 2017
MySQL 版本: 8.0.27
引入 MySQL ,是为了跟 SQL Server 做对比
SQL Server 建表并初始化数据
CREATE TABLE tbl_interface_call_times ( id BIGINT PRIMARY KEY IDENTITY(1,1), call_month INT NOT NULL, interface varchar(50) NOT NULL , times INT NOT NULL ); INSERT INTO tbl_interface_call_times(call_month, interface, times) VALUES (202301, 'interface1', 800), (202301, 'interface2', 1000), (202301, 'interface3', 100), (202302, 'interface1', 833), (202302, 'interface2', 834), (202302, 'interface3', 134), (202302, 'interface4', 243), (202302, 'interface5', 2143);
MySQL 建表并初始化数据
CREATE TABLE tbl_interface_call_times ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, call_month INT NOT NULL COMMENT '月份', interface varchar(50) NOT NULL COMMENT '接口', times INT NOT NULL COMMENT '调用次数', PRIMARY KEY(id) ) COMMENT '接口调用次数'; INSERT INTO tbl_interface_call_times(call_month, interface, times) VALUES (202301, 'interface1', 800), (202301, 'interface2', 1000), (202301, 'interface3', 100), (202302, 'interface1', 833), (202302, 'interface2', 834), (202302, 'interface3', 134), (202302, 'interface4', 243), (202302, 'interface5', 2143);
汇总每个月的付费, SQL 该如何写?
很简单的啦,如下所示
SELECT call_month, SUM( CASE WHEN times * 0.03 > 25 THEN 25 ELSE times * 0.03 END ) monthFee FROM tbl_interface_call_times GROUP BY call_month
通用写法, SQL Server 和 MySQL 都支持
我们看下查询结果
一切都很正常,觉得世界真美好!
问题复现
我们不能光玩数据库吧?
不得像这样雨露均沾?
必须把 spring-boot 、 MyBatis-Plus 安排上
mysql-jdbc 版本: 8.0.21 , mssql-jdbc 版本: 6.2.1.jre8
完整代码:mybatis-plus-dynamic-datasource
访问: http://localhost:8081/interface/summary?startMonth=202301&endMonth=202302
你会发现,你心心念念的 surprise 终于出现了!
正确应该是 86.3,.3 哪去了?
直查数据库是没问题的呀
莫非 MyBatis-Plus 有问题?
我们切到 MySQL 试试;将 InterfaceCallTimesServiceImpl 上的数据源改成 mysql_db
然后重启,我们再访问: http://localhost:8081/interface/summary?startMonth=202301&endMonth=202302
这说明应该不是 MyBatis 的问题,那不完犊子了?
问题解决
是不是束手无策了? 也不是,我们可以 Bing 一下的嘛
你会发现说的都是批量 insert 的时候, BigDecimal 有精度丢失
单条插入的时候,是没有精度丢失的
然后了,大家试出了一条件论: 批量插入数据时,如果插入的数据精度不统一,最终入库的数据精度统一按最低的精度入库
虽说我们只是查询,莫非也需要 精度统一 ?
精度统一
试试呗,反正又不要钱
重启,神奇的事情发生了
.3 它回来了! 相信此刻的你肯定有一种与知己久别重逢的激动
问题貌似解决了,但说实话,这种处理方式你用的放心吗?
升级 mssql-jdbc 版本
我们好好捋一下,程序从 SQL Server 获取数据,经历了哪些环节?
只有三个: MyBatis-Plus -> mssql-jdbc -> SQL Server
前面我们已经排除了 SQL Server 和 MyBatis-Plus
那问题肯定就出在 mssql-jdbc 身上了
问题又来了,该如何从 mssql-jdbc 上找问题了?
开源的东西从它的官方找相关的 issue ,肯定不止我们遇到这样的问题,那么肯定有人会给官方提了 issue
issu