news 2026/6/10 17:34:30

MyBatis时间区间查询异常排查(达梦数据库)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection@2137505285wrapping dm.jdbc.driver.DmdbConnection@281d9254]willnotbe managedbySpring==>Preparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted=0AND(device_id=?ANDday_timeBETWEEN?AND?)ORDERBYdevice_idASC,day_timeASC==>Parameters: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,deleted<==Row:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0<==Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession@7b5825b6]-- 改成这样也不行Creating a new SqlSession SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession@74b53705]wasnotregisteredforsynchronization because synchronizationisnotactive JDBC Connection[HikariProxyConnection@76633552wrapping dm.jdbc.driver.DmdbConnection@69b5bb66]willnotbe managedbySpring==>Preparing:SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted=0AND(device_id=?AND(day_time>=?ANDday_time<=?))ORDERBYdevice_idASC,day_timeASC==>Parameters: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,deleted<==Row:57,1,2026-05-0100:00:00.000000,0.0,2026-05-2518:03:40.677000,2026-05-2518:03:40.677000,0<==Total:1Closing non transactional SqlSession[org.apache.ibatis.session.defaults.DefaultSqlSession@74b53705]
  • 执行SQL就可以,可能是客户端处理了
SELECTid,device_id,day_time,failure,create_time,update_time,deletedFROMtb_failureWHEREdeleted=0AND(device_id=1ANDday_timeBETWEEN'2026-04-01 00:00:00.0'AND'2026-04-30 23:59:59.999999999')ORDERBYdevice_idASC,day_timeASC

二、解决

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驱动在将JavaTimestamp对象(可能携带纳秒精度)发送给数据库前,可能将超出部分(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位微秒精度。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 3:47:57

C# 终于支持 union types 了

C# 15 中的联合 unionIntrounion 联合类型在 C# 中的需求一直很高&#xff0c;现在终于要来了。从 .NET 11 Preview 2 开始&#xff0c;C# 15 引入了 union 关键字。union 关键字声明一个值恰好是固定类型集合中的一种&#xff0c;并且具有编译器强制执行的穷尽模式匹配。C# 的…

作者头像 李华
网站建设 2026/5/28 3:46:27

别再自己造轮子了!用Ba-Scanner插件5分钟搞定UniApp扫码功能(支持连续扫、自定义UI)

别再重复造轮子&#xff01;用Ba-Scanner插件5分钟实现UniApp专业级扫码功能 在移动应用开发中&#xff0c;扫码功能几乎是电商、物流、票务等场景的标配需求。但很多开发者依然在重复编写基础扫码模块——调试摄像头兼容性、处理不同格式的二维码、适配各种Android/iOS设备...…

作者头像 李华
网站建设 2026/5/30 0:19:16

人工智能-现代方法(四)

20260526 1、概率推断&#xff08;probabilistic inference&#xff09;&#xff1a;给定观测证据&#xff0c;为某个查询命题计算后验概率。最直接的处理方式&#xff0c;就是先得到一个完全联合分布&#xff08;所有变量的组合概率表格&#xff09;&#xff0c;在表格中按项求…

作者头像 李华