MyBatis时间区间查询异常排查解决过程(达梦数据库)
更新时间:2026年06月25日 09:26:16 作者:墨_风
这篇文章主要介绍了MyBatis时间区间查询异常排查解决的相关资料,文中通过代码详细介绍了时间精度差异导致的异常,并提供了两种解决思路,需要的朋友可以参考下
一、问题
1.1、版本
- JDK 版本:JDK 17 (龙井JDK)
- Spring Boot 版本:Spring Boot 3.3.0
- MyBatis / MyBatis-Plus 版本:MyBatis-Plus 3.5.16,使用的是 mybatis-plus-spring-boot3-starter(专门适配 Spring Boot 3)。同时引入了 mybatis-plus-jsqlparser(用于 SQL 解析和分页等功能)。
- 达梦数据库驱动: 8.1.3.140
1.2、问题
- mybatis 时间区间查询,查出异常数据
- mybatis的SQL以及 查询出的数据,很明显,时间区间有问题
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b5825b6] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@2137505285 wrapping dm.jdbc.driver.DmdbConnection@281d9254] will not be managed by Spring ==> Preparing: SELECT id, device_id, day_time, failure, create_time, update_time, deleted FROM tb_failure WHERE deleted = 0 AND ( device_id = ? AND day_time BETWEEN ? AND ? ) ORDER BY device_id ASC, day_time ASC ==> Parameters: 1(String), 2026-04-01 00:00:00.0(Timestamp), 2026-04-30 23:59:59.999999999(Timestamp) <== Columns: id, device_id, day_time, failure, create_time, update_time, deleted <== Row: 57, 1, 2026-05-01 00:00:00.000000, 0.0, 2026-05-25 18:03:40.677000, 2026-05-25 18:03:40.677000, 0 <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7b5825b6] -- 改成这样也不行 Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74b53705] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@76633552 wrapping dm.jdbc.driver.DmdbConnection@69b5bb66] will not be managed by Spring ==> Preparing: SELECT id, device_id, day_time, failure, create_time, update_time, deleted FROM tb_failure WHERE deleted = 0 AND ( device_id = ? AND (day_time > = ? AND day_time <= ?) ) ORDER BY device_id ASC, day_time ASC ==> Parameters: 1(String), 2026-04-01 00:00:00.0(Timestamp), 2026-04-30 23:59:59.999999999(Timestamp) <== Columns: id, device_id, day_time, failure, create_time, update_time, deleted <== Row: 57, 1, 2026-05-01 00:00:00.000000, 0.0, 2026-05-25 18:03:40.677000, 2026-05-25 18:03:40.677000, 0 <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@74b53705]
- 执行SQL就可以,可能是客户端处理了
SELECT id, device_id, day_time, failure, create_time, update_time, deleted FROM tb_failure WHERE deleted = 0 AND ( device_id = 1 AND day_time BETWEEN '2026-04-01 00:00:00.0' AND '2026-04-30 23:59:59.999999999' ) ORDER BY device_id ASC, day_time ASC
二、解决
2.1、问题分析
- 差异点:
MyBatis日志显示参数day_time BETWEEN ? AND ?的结束值是2026-04-30 23:59:59.999999999(9位纳秒),但实际返回了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'。 - 优点:逻辑清晰,完全不受秒精度影响,且能正确处理索引。
- 思路:查询4月份数据时,范围定为
- 显式截断参数精度(如果无法修改业务逻辑):如果你必须使用“月末最后一刻”的写法,可以在传入MyBatis之前,手动将
Timestamp对象的纳秒部分截断,使其符合达梦的6位微秒精度。
总结
到此这篇关于MyBatis时间区间查询异常排查解决过程的文章就介绍到这了,更多相关MyBatis时间区间查询异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
使用java web 在jsp文件及Class中连接MySQL和SQLserver 的驱动方法
这篇文章主要介绍了使用java web 在jsp文件及Class中连接MySQL和SQLserver的驱动方法的相关资料,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下2016-10-10
使用Apache POI和SpringBoot实现Excel文件上传和解析功能
在现代企业应用开发中,数据的导入和导出是一项常见且重要的功能需求,Excel 作为一种广泛使用的电子表格工具,常常被用来存储和展示数据,下面我们来看看如何使用Apache POI和SpringBoot实现Excel文件上传和解析功能吧2025-01-01


最新评论