Java持久性标准;将表达式<timestamp>转换为表达式<long>?</long> </timestamp>

时间:2011-02-11 10:09:17

标签: java generics jpa criteria

我正在使用CriteriaBuilder和CriteriaQuery来构建我对数据库的查询,但是我遇到了一个我不知道如何解决的问题,因为我对这个叫做JPA的整个考验都很陌生。

在Java中,我有一个名为时间戳的属性,用于名为报告的类,并且它设置为相同的 @TemporalType 。 我还有一个名为 Affiliate 的课程,其中包含报告对象的列表。

在我的查询中,我想获取最后 Affiliate.maxSilenceMinutes 中没有报告的所有 Affiliate 对象。< / p>

我的问题:

  1. 标准化JPA中是否有任何方法可以修改日期?就像 CriteriaBuilder.subtractMilliseconds(Expression&lt; Timestamp&gt;,Long)一样?
  2. 如果没有,有没有办法将表达式&lt;时间戳&gt; 强制转换为表达式&lt; Long&gt; ,以便我可以减去 currentTimestamp literal获取 CriteriaBuilder.lessThanOrEqualTo(greatReportTimestampMs,minimumAllowedMs)的最小值
  3. 我知道这可能是一个令人困惑的问题,但主要部分很简单:是否可以将表达式&lt;时间戳&gt; 转换为表达式&lt; Long&gt; ?如果我尝试使用 .as(Long.class)方法,但是它应该是大多数数据库中默认的基础数据类型,它会引发异常吗?

    希望你们可以提供帮助,因为我觉得有点困惑:)

2 个答案:

答案 0 :(得分:0)

如果您知道要在查询时减去的值, 你可以事先减去:

Calendar c = new Calendar();
c.setTime(timestamp.getTimestamp());
c.add(DAY, - someNumberOfDays);  //or whatever unit you want
Date d = c.getTime();

如果没有,您可能需要调用数据库函数来进行减法运算 CriteriaBuilder.function()

CriteriaBuilder.lessThanOrEqual()适用于可比较对象。时间戳具有可比性。所以你可以通过new Timestamp(long ms)构建一个时间戳 并将其与其他表达式进行比较。

我希望这会有所帮助。

答案 1 :(得分:0)

这不是内置于Hibernate中的,因此您需要某种自定义函数。

JDBC标准包括一个函数转义{fn TIMESTAMPADD( SQL_TSI_SECOND, secs, timestamp)},它应该被转换为目标数据库的正确SQL,但并非所有JDBC实现都提供它。因此,您可以将自定义的StandardJDBCEscapeFunction添加到Hibernate的Dialect中,以获得所需的结果。

如果你没有那个,你必须找出正确的数据库特定实现是什么,这里有很多变化。例如:

Oracle:(timestamp + secs/86400)
SQLServer:DATEADD(ss,secs,timestamp)
DB2:(timestamp + secs SECONDS)
MySQL:DATE_ADD(timestamp, INTERVAL secs SECONDS)

一旦知道,就可以使用正确的表达式作为SQL标准。

事实上,日期时间操作在Dialect中没有标准化,并且没有在许多JDBC中完全实现,这意味着您尝试做的事情将很难以数据库中立的方式编写。