java.util.Date与MySQL Datetime列比较异常 按指定日期查询无结果
查询无法命中匹配记录的核心原因
- 你当前的JPA查询对
datetime类型的createdAt字段做了精确等值匹配,而非匹配日期部分
你传入的createdAt参数是经yyyy-MM-dd格式解析后的2021-03-03 00:00:00精确时间点,但数据库datetime列存储的是当天任意时分秒的完整时间(比如2021-03-03 09:12:30、2021-03-03 18:45:11),两者时间点不相等,等值判断自然无法命中任何记录。 - 存在时区偏移的潜在隐患
你使用的SimpleDateFormat没有显式指定时区,默认依赖JVM运行时的默认时区,若应用时区与数据库时区不一致,即使后续调整查询逻辑,也可能出现日期跨天的偏移问题。
通用修复方案
匹配指定日期的所有datetime记录,最稳妥的方式是采用左闭右开的时间范围查询,避免数据库函数导致的索引失效问题:
- 先把传入的日期字符串转换为两个边界时间:
- 起始时间:指定日期的
00:00:00 - 结束时间:指定日期次日的
00:00:00
- 起始时间:指定日期的
- 调整JPA查询的判断逻辑为时间范围匹配:
@Query(value = "" + "FROM MarketingForm mf " + "WHERE " + "(:startDate is null OR mf.createdAt >= :startDate) " + "AND (:endDate is null OR mf.createdAt < :endDate) " + "AND (:verticalId is null OR mf.verticalId = :verticalId) " + "AND (:tag is null OR mf.tag = :tag)" ) List<MarketingForm> findAllByCreatedAtRangeAndVerticalIdAndTag( @Param("startDate") Date startDate, @Param("endDate") Date endDate, @Param("verticalId") Long verticalId, @Param("tag") String tag );
注意:不要直接用
DATE(mf.createdAt) = :createdDate这类数据库函数判断,会导致createdAt字段上的索引失效,大幅降低查询性能,优先使用范围查询。
内容的提问来源于stack exchange,提问作者Gurucharan Sharma
相关产品推荐
相关产品推荐

