2

我通过 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);

当然这不起作用,因为您不能直接比较 aDate和 a Time。如果这是一个 SQL 查询,那么我会使用一些特定于 DBMS 的日期函数来比较它们,但是如何比较 JPA 中的日期和时间呢?

4

3 回答 3

3

如果您使用 JPA,您可以使用 @Temporal(TemporalType.TIME) 它只会返回 TIMESTAMP 的时间部分。喜欢:@Temporal(TemporalType.TIME) 日期 getDateTime()

于 2012-11-09T04:54:42.580 回答
2

为什么不使用本机查询,然后利用您熟悉的数据库特定功能。一旦你有了 Native Query,你就可以将java.sql.Time对象转换为 long 并执行它。

EntityManager API 文档

例如,如果您使用的是 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 子句。

于 2012-11-01T16:46:07.817 回答
1

没有任何简单或标准化的方法可以仅与使用 JPA2 的现有日期时间/时间戳列的时间(或日期)组件进行比较。选项:

  1. 使用本机查询。 如果您需要秒精度(不是毫秒),kmb385 的答案有效。我认为更常见的原生 SQL 方法是使用 CAST 或 EXTRACT 仅与时间组件进行比较。

  2. 将另一列添加到仅包含日期时间的时间组件的表/视图中,并使用它进行比较。您可能还会使用@Temporal(TemporalType.TIME)注释向 Foo 添加另一个字段。

于 2012-11-09T14:31:39.570 回答