我正在通过JPA使用Hibernate,我需要按照Date
属性的时间部分过滤记录。
public class Foo {
Date getDateTime() {
// Returns a date and time value.
}
}
Time startTime = ...;
Time endTime = ...;
TypedQuery<Foo> query = entityManager.createQuery("SELECT foo FROM Foo foo where :startTime <= foo.dateTime AND foo.dateTime <= :endTime", Foo.class);
query.setParameter("startTime", startTime);
query.setParameter("endTime ", endTime);
当然这不起作用,因为您无法直接比较Date
和Time
。如果这是一个SQL查询,那么我会使用一些特定于DBMS的日期函数来比较它们,但是如何比较JPA中的日期和时间?
答案 0 :(得分:3)
如果您使用的是JPA,则可以使用 @Temporal(TemporalType.TIME) 它将仅返回TIMESTAMP的Time部分。 喜欢: @Temporal(TemporalType.TIME) 日期getDateTime()
答案 1 :(得分:2)
为什么不使用Native Query,然后利用您熟悉的数据库特定功能。获得Native Query后,您可以将java.sql.Time
个对象转换为long并执行它。
EntityManager API Documentation
例如,如果您使用的是Oracle。
long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
long startTimeMillis = (startTime.getTime() % MILLIS_PER_DAY)/1000;
long stopTimeMillis = (endTime.getTime() % MILLIS_PER_DAY)/1000;
entityManager
.createNativeQuery(
"select * from foo where to_number(to_char(date_time, 'sssss')) between ?1 and ?2", Foo.class)
.setParameter(1, startTimeMillis)
.setParameter(2, stopTimeMillis).getResultList();
实际查询将根据您的数据库风格而有所不同,但是创建NativeQuery应该允许您利用特定于数据库的基础供应商功能。
解决此挑战的另一种方法是创建一个视图,其中包含一个包含日期数据类型的列的时间部分的列。这将允许您以代码中透明的方式利用底层数据库技术。设置此列后,您将在查询中建立正确的where子句。
答案 2 :(得分:1)
没有任何简单或标准化的方法可以仅使用JPA2与现有日期时间/时间戳列的时间(或日期)组件进行比较。选项:
使用原生查询。如果您需要秒精度(而不是毫秒),kmb385's answer可以正常工作。我认为更常见的本机SQL方法是使用CAST或EXTRACT来仅与时间组件进行比较。
将另一列添加到仅包含日期时间的时间组件的表/视图中,并使用该列进行比较。您可能还会使用@Temporal(TemporalType.TIME)
注释向Foo添加另一个字段。