如何与 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>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 查询进行时间戳比较?的主要内容,如果未能解决你的问题,请参考以下文章