You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中如何通过日期匹配Timestamp列实现数据查询?

问题描述

我通过以下代码获取了一个格式为2024-09-10 00:00:00.0的Date对象myCurrentDate:

Date myCurrentDate = calendarRepository.getMyCurrentDate();

数据库的product_table表中有一个timestamp类型的create_date列,数据示例如下:

product_namecreate_date
Sugar2024-09-10 11:37:25
Chips2024-09-08 12:20:52
Coffee2024-09-10 15:12:33
Oranges2024-09-10 20:52:15

我需要查询当天创建的所有产品(即Sugar、Coffee、Oranges),但当前使用的查询代码返回空结果:

List<Products> productsReults= productRepository.findByCrtDt(myCurrentDate);

对应的JPA Repository定义:

List<Products> findByCrtDt(Date myCurrentDate);

原因是myCurrentDate的时分秒为00:00:00.0,和数据库中带具体时分秒的时间戳不匹配。要求不能修改数据库列类型(从Timestamp改为Date),请问如何修改查询逻辑?


解决方案

方法1:按当天时间范围查询

计算出myCurrentDate当天的起始时间(00:00:00)和次日起始时间(次日00:00:00),用Between匹配落在该区间内的数据:

首先在Repository中定义方法:

List<Products> findByCreateDateBetween(Date startDate, Date endDate);

然后在业务代码中生成时间范围:

// 当天起始时间就是myCurrentDate本身
Date startOfDay = myCurrentDate;
// 计算次日00:00:00
Calendar calendar = Calendar.getInstance();
calendar.setTime(myCurrentDate);
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date endOfDay = calendar.getTime();

// 执行查询
List<Products> productsResults = productRepository.findByCreateDateBetween(startOfDay, endOfDay);

方法2:用数据库日期函数忽略时分秒

通过JPA调用数据库的日期处理函数,提取日期部分进行匹配,Repository方法定义如下:

@Query("SELECT p FROM Products p WHERE FUNCTION('DATE', p.createDate) = FUNCTION('DATE', :currentDate)")
List<Products> findByCreateDateDatePart(@Param("currentDate") Date currentDate);

注意:不同数据库的日期函数名称有差异:

  • MySQL/MariaDB:使用DATE()函数,上述写法直接可用
  • PostgreSQL:可替换为DATE_TRUNC('day', p.createDate) = DATE_TRUNC('day', :currentDate)
  • Oracle:替换为TRUNC(p.createDate) = TRUNC(:currentDate)

方法3:结合Java 8时间API简化查询

如果实体类允许调整字段类型(不修改数据库列),将createDate改为LocalDateTime:

@Column(name = "create_date", columnDefinition = "TIMESTAMP")
private LocalDateTime createDate;

然后在Repository中定义基于时间范围的衍生方法:

List<Products> findByCreateDateBetween(LocalDateTime startOfDay, LocalDateTime endOfDay);

业务代码中转换时间:

LocalDate currentLocalDate = myCurrentDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDateTime startOfDay = currentLocalDate.atStartOfDay();
LocalDateTime endOfDay = currentLocalDate.plusDays(1).atStartOfDay();

List<Products> productsResults = productRepository.findByCreateDateBetween(startOfDay, endOfDay);

内容的提问来源于stack exchange,提问作者craftdeer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:06:10