如何在Hibernate中比较日期

18

在我的数据库中,日期格式为2012-04-09 04:02:532012-04-09 04:04:512012-04-08 04:04:51等。我需要检索出具有当前日期的数据,即只需匹配2012-04-09'。我该如何使用Hibernate Criteria实现?

8个回答

30

使用Restrictions.between()生成一个where子句,其中日期列介于'2012-04-09 00:00:00'和'2012-04-09 23:59:59'之间。

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date fromDate = df.parse("2012-04-09 00:00:00");
Date toDate = df.parse("2012-04-09 23:59:59");

criteria.add(Restrictions.between("dateField", fromDate, toDate));
请注意,Criteria API 中使用的所有属性都是 Java 属性名称,而不是实际列名称。

更新:仅使用 JDK 获取当前日期的 fromDate 和 toDate。

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date fromDate = calendar.getTime();

calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
Date toDate = calendar.getTime();

criteria.add(Restrictions.between("dateField", fromDate, toDate));

如何从当前日期获取fromDate和toDate - Romi
@Ken Chan,非常感谢你发布了有关单个日期比较的日期比较。我会在解析方法中为23:59:59给你+1。 - OO7
这很有帮助。我认为Hibernate应该提供一个比较日期而不是时间的函数。 - Olakunle Awotunbo
尽管这对于所有实际目的都有效,但23:59:59仍不完全等同于EOD。我会让Java帮我解决这个问题:LocalDate.now().atTime(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant() - EFreak

2
像这样吗?
criteria.add(Expression.eq("yourDate", aDate))

使用Expression.between("yourDate", aDate, aDate+1)怎么样? - titogeo
这对我没用,我认为它做的是完全相同的事情,比较日期的最佳方法是第一个答案。 - Phil_Charly

2
fromDate.setTime(new Date());
fromDate.set(Calendar.HOUR_OF_DAY, 0);
fromDate.set(Calendar.MINUTE, 0);
fromDate.set(Calendar.SECOND, 0);
fromDate.set(Calendar.MILLISECOND, 0);

这段代码非常危险... 如果日期切换到夏令时(例如06.04.1980),您将遇到以下异常!!!

 java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1day


HQL: from human pat where year(pat.birthdate) = :start_day and month(pat.birthdate) = :start_month and year(pat.birthdate) = :start_year ");

params.put("start_day", startDate.get(Calendar.DAY_OF_MONTH));
params.put("start_month", startDate.get(Calendar.MONTH) + 1);
params.put("start_year", startDate.get(Calendar.YEAR));

年/月/日函数使用底层的数据库函数(extract,...)并仅比较这些值。因此,我不需要将时间设置为0,这会导致上述描述的异常。这只是我解决问题的一个例子!也许它有所帮助。

1

最简单的方法是获取所有日期在给定日期的开始和结束之间的记录:

WHERE date BETWEEN :from AND :to

在您的Java代码中计算fromto

用于计算午夜:

import static org.apache.commons.lang.time.DateUtils.ceiling;
import static org.apache.commons.lang.time.DateUtils.truncate;

Date someDay = new Date();
Date from = truncate(someDay, Calendar.DAY_OF_MONTH);
Date to = new Date(ceiling(someDay, Calendar.DAY_OF_MONTH).getTime() - 1);

我没明白。ceiling和truncate是用来做什么的? - Romi
@Romi:你需要以某种方式计算一天的开始(2012年4月9日00:00:00 CEST)和结束时间(2012年4月9日23:59:59 CEST)。 - Tomasz Nurkiewicz
@Romi:是的,truncate 函数返回给定日期的开始时间(00:00),而 ceiling 函数则返回下一天的开始时间。 - Tomasz Nurkiewicz

1

如何在Hibernate中实现已经说过了。您可以使用Java代码准备Timestamp对象,例如以下方法:

Calendar cFrom = Calendar.getInstance();
cFrom.setTime(new Date()); /* today */
cFrom.set(Calendar.HOUR_OF_DAY, 0);
cFrom.set(Calendar.MINUTE, 0);
cFrom.set(Calendar.SECOND, 0);
cFrom.set(Calendar.MILLISECOND, 0);
Timestamp from = new Timestamp(cFrom.getTime().getTime());
Calendar cTo = Calendar.getInstance();
cTo.setTime(new Date()); /* today */
cTo.set(Calendar.HOUR_OF_DAY, 23);
cTo.set(Calendar.MINUTE, 59);
cTo.set(Calendar.SECOND, 59);
cTo.set(Calendar.MILLISECOND, 999);
Timestamp to = new Timestamp(cTo.getTime().getTime());

final String QUERY = ""
  + "SELECT tr "
  + "FROM Type tr "
  + "WHERE tr.timestamp >= :timestampFrom AND tr.timestamp <= :timestampTo";
Query query = entityManager.createQuery(QUERY);
query.setParameter("timestampFrom", from);
query.setParameter("timestampTo", to);
@SuppressWarnings("unchecked")
List<Type> ts = (List<Type>)query.getResultList();

0
Restrictions.between("dateColumn", midnight1, midnight2)

0
The following code will work

Calendar fromDate = Calendar.getInstance();
fromDate.setTime(new Date());
fromDate.set(Calendar.HOUR_OF_DAY, 0);
fromDate.set(Calendar.MINUTE, 0);
fromDate.set(Calendar.SECOND, 0);
fromDate.set(Calendar.MILLISECOND, 0);

Calendar toDate = Calendar.getInstance();
toDate.setTime(new Date());
toDate.set(Calendar.HOUR_OF_DAY, 23);
toDate.set(Calendar.MINUTE, 59);
toDate.set(Calendar.SECOND, 59);
toDate.set(Calendar.MILLISECOND, 999);

criteria.add(Restrictions.between("loadDate", fromDate.getTime(),
                    toDate.getTime()));

0

// Hibernate 4.3中的日期时间比较

     Select c from Customer c where c.date<{d '2000-01-01'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接