一、问题1.1、版本JDK 版本JDK 17 龙井JDKSpring Boot 版本Spring Boot 3.3.0MyBatis / MyBatis-Plus 版本MyBatis-Plus 3.5.16使用的是 mybatis-plus-spring-boot3-starter专门适配 Spring Boot 3。同时引入了 mybatis-plus-jsqlparser用于 SQL 解析和分页等功能。达梦数据库驱动: 8.1.3.1401.2、问题mybatis 时间区间查询查出异常数据mybatis的SQL以及 查询出的数据很明显时间区间有问题Creating a new SqlSession SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession7b5825b6]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection2137505285wrapping dm.jdbc.driver.DmdbConnection281d9254]willnotbe managedbySpringPreparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id?ANDday_timeBETWEEN?AND?)ORDERBYdevice_idASC,day_timeASCParameters:1(String),2026-04-0100:00:00.0(Timestamp),2026-04-3023:59:59.999999999(Timestamp)Columns: id,device_id,day_time,failure,create_time,update_time,deletedRow:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession7b5825b6]-- 改成这样也不行Creating a new SqlSession SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession74b53705]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection76633552wrapping dm.jdbc.driver.DmdbConnection69b5bb66]willnotbe managedbySpringPreparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id?AND(day_time?ANDday_time?))ORDERBYdevice_idASC,day_timeASCParameters:1(String),2026-04-0100:00:00.0(Timestamp),2026-04-3023:59:59.999999999(Timestamp)Columns: id,device_id,day_time,failure,create_time,update_time,deletedRow:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession74b53705]执行SQL就可以可能是客户端处理了SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id1ANDday_timeBETWEEN2026-04-01 00:00:00.0AND2026-04-30 23:59:59.999999999)ORDERBYdevice_idASC,day_timeASC二、解决2.1、问题分析差异点MyBatis日志显示参数day_time BETWEEN ? AND ?的结束值是2026-04-30 23:59:59.9999999999位纳秒但实际返回了2026-05-01 00:00:00.000000的数据。根本原因精度上限达梦数据库的TIMESTAMP类型最大只支持 6 位小数秒精度微秒级 。你传入的999999999纳秒即9位超出了其处理能力。驱动行为达梦JDBC驱动在将Java的Timestamp对象可能携带纳秒精度发送给数据库前可能将超出部分9位 - 6位进行了四舍五入处理。溢出推论999999999纳秒四舍五入到微秒6位后无限接近下一秒的000000。再加上达梦内部的时间比较逻辑导致条件 2026-04-30 23:59:59.999999实际被当作 2026-05-01 00:00:00处理从而拉取了5月1日的数据。2.2、解决思路调整代码逻辑避免使用“23:59:59…” 这是最稳健的做法绕开了精度问题。思路查询4月份数据时范围定为day_time 2026-04-01且day_time 2026-05-01。优点逻辑清晰完全不受秒精度影响且能正确处理索引。显式截断参数精度如果无法修改业务逻辑如果你必须使用“月末最后一刻”的写法可以在传入MyBatis之前手动将Timestamp对象的纳秒部分截断使其符合达梦的6位微秒精度。
MyBatis时间区间查询异常排查(达梦数据库)
发布时间:2026/5/28 3:52:02
一、问题1.1、版本JDK 版本JDK 17 龙井JDKSpring Boot 版本Spring Boot 3.3.0MyBatis / MyBatis-Plus 版本MyBatis-Plus 3.5.16使用的是 mybatis-plus-spring-boot3-starter专门适配 Spring Boot 3。同时引入了 mybatis-plus-jsqlparser用于 SQL 解析和分页等功能。达梦数据库驱动: 8.1.3.1401.2、问题mybatis 时间区间查询查出异常数据mybatis的SQL以及 查询出的数据很明显时间区间有问题Creating a new SqlSession SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession7b5825b6]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection2137505285wrapping dm.jdbc.driver.DmdbConnection281d9254]willnotbe managedbySpringPreparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id?ANDday_timeBETWEEN?AND?)ORDERBYdevice_idASC,day_timeASCParameters:1(String),2026-04-0100:00:00.0(Timestamp),2026-04-3023:59:59.999999999(Timestamp)Columns: id,device_id,day_time,failure,create_time,update_time,deletedRow:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession7b5825b6]-- 改成这样也不行Creating a new SqlSession SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession74b53705]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection76633552wrapping dm.jdbc.driver.DmdbConnection69b5bb66]willnotbe managedbySpringPreparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id?AND(day_time?ANDday_time?))ORDERBYdevice_idASC,day_timeASCParameters:1(String),2026-04-0100:00:00.0(Timestamp),2026-04-3023:59:59.999999999(Timestamp)Columns: id,device_id,day_time,failure,create_time,update_time,deletedRow:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession74b53705]执行SQL就可以可能是客户端处理了SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted0AND(device_id1ANDday_timeBETWEEN2026-04-01 00:00:00.0AND2026-04-30 23:59:59.999999999)ORDERBYdevice_idASC,day_timeASC二、解决2.1、问题分析差异点MyBatis日志显示参数day_time BETWEEN ? AND ?的结束值是2026-04-30 23:59:59.9999999999位纳秒但实际返回了2026-05-01 00:00:00.000000的数据。根本原因精度上限达梦数据库的TIMESTAMP类型最大只支持 6 位小数秒精度微秒级 。你传入的999999999纳秒即9位超出了其处理能力。驱动行为达梦JDBC驱动在将Java的Timestamp对象可能携带纳秒精度发送给数据库前可能将超出部分9位 - 6位进行了四舍五入处理。溢出推论999999999纳秒四舍五入到微秒6位后无限接近下一秒的000000。再加上达梦内部的时间比较逻辑导致条件 2026-04-30 23:59:59.999999实际被当作 2026-05-01 00:00:00处理从而拉取了5月1日的数据。2.2、解决思路调整代码逻辑避免使用“23:59:59…” 这是最稳健的做法绕开了精度问题。思路查询4月份数据时范围定为day_time 2026-04-01且day_time 2026-05-01。优点逻辑清晰完全不受秒精度影响且能正确处理索引。显式截断参数精度如果无法修改业务逻辑如果你必须使用“月末最后一刻”的写法可以在传入MyBatis之前手动将Timestamp对象的纳秒部分截断使其符合达梦的6位微秒精度。