如何与 JPA 查询进行时间戳比较?

Posted

技术标签:

【中文标题】如何与 JPA 查询进行时间戳比较?【英文标题】:How to do a timestamp comparison with JPA query? 【发布时间】:2011-02-02 02:24:46 【问题描述】:

我们需要确保 JPQL 查询只返回过去 30 天内的结果。下面是一个例子:

Date now = new Date();
Timestamp thirtyDaysAgo = new Timestamp(now.getTime() - 86400000*30);

Query query = em.createQuery(
  "SELECT msg FROM Message msg "+
  "WHERE msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > ts, '"+thirtyDaysAgo+"'");
List result = query.getResultList();

这是我们收到的错误:

<907835>

【参考方案1】:

所以您输入的查询不是 JPQL(您可以通过参考 JPA 规范看到)。如果要将字段与日期进行比较,则输入日期作为查询的参数

msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > :param

这不是 SQL。

【讨论】:

对于此处记录的 JPA 实现,这是有效的 JPQL:openjpa.apache.org/builds/latest/docs/manual/… 使用“JDBC 转义语法”。您应该考虑对尝试使用新技术的人表示同情。 是的,你是对的;我忘记了 RDBMS JPQL 是多么具体。建议仍然是避免这种语法,因为根据 JPA 规范,您依赖于支持它的 JDBC 驱动程序,并且使用参数查询实际上要干净得多。 提供引用。【参考方案2】:

您使用的 OpenJPA 版本可能不支持 JDBC 转义语法。最新 1.2.x 版本的文档在这里:http://openjpa.apache.org/builds/1.2.2/apache-openjpa-1.2.2/docs/manual/manual.html#jpa_langref_lit。

前面提到的文档是指 OpenJPA 2.0.0(最新)的文档:http://openjpa.apache.org/builds/latest/docs/manual/jpa_langref.html#jpa_langref_lit

也就是说,您有什么理由要在您的 JPQL 中注入一个字符串?像下面的sn-p这样的东西呢?

Date now = new Date();
Date thirtyDaysAgo = new Date(now.getTime() - (30 * MS_IN_DAY));

Query q = em.createQuery("Select m from Message m " 
    + "where m.targetTime < :now and m.targetTime > :thirtyDays");
q.setParameter("now", now); 
q.setParameter("thirtyDays", thirtyDaysAgo);

List<Message> results = (List<Message>) q.getResultList();

【讨论】:

我更喜欢使用参数“now”而不是 DataNucleus 建议中的 JPQL 函数“current_timestamp”,因为该函数返回数据库服务器上的时间,而 new Date() 返回数据库服务器上的时间Java 容器。如果它们不是同一台机器,当时钟不同步时,这可能会导致错误。 仅供参考,在 JPQL 中,您可以使用 TypedQuery 来避免强制转换。

以上是关于如何与 JPA 查询进行时间戳比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用FFmpeg进行时间戳定位

php怎么将指定日期转换为时间戳?

Mysql查询将返回数据库中时间戳之间的空闲槽

如何使用 SQL 显示两个不同区域中时间戳之间的实时差异?

将五个小时添加到时间戳字段

如何在 DB2 SQL 中创建一个给出给定行时间戳之前 5 分钟内所有行总和的列?