我正在重写一个巨大的搜索查询,最初是在Hibernate Criteria中创建的。我试图只使用标准的JPA解决方案。我面临的问题是,我想制作一个像这样的where子句:
select ... where (stopTime - startTime) > minimalLength
这似乎不适用于Calendar值,因为我无法使用Criteria API对它们进行算术运算。有解决方案吗?
更新1
正如答案中提到的那样(现在已删除),Criteria API具有sum
,diff
,prod
方法,但这些方法的签名为:
<N extends java.lang.Number> Expression<N>
method(Expression<? extends N> x, Expression<? extends N> y)
<N extends java.lang.Number> Expression<N>
method(N x, Expression<? extends N> y)
<N extends java.lang.Number> Expression<N>
method(Expression<? extends N> x, N y)
因此它们不适用于Calendar
(甚至Date
)。
更新2
我想,我走在正确的轨道上。我决定使用 CriteriaBuilder 的function
方法,并使用它来调用(不幸的是供应商特定的)datediff
SQL Server方法。它看起来像这样:
builder.function("datediff", Integer.class, builder.literal("second"), startTime, stopTime)
这个几乎有效,唯一的问题是,datediff
不能与 String 一起作为第一个参数,它需要一个关键字(即&# 34;第二个&#34;没有引号)。有没有人知道将文字传递给函数的方法?
答案 0 :(得分:1)
好吧,最后我放弃了,用HQL代替Criteria API。左,只希望我的问题将在Criteria API的下一次迭代中修复......
答案 1 :(得分:1)
我遇到了同样的问题,遇到了你在更新2中遇到的同样死胡同。
我能想到的唯一解决方法是创建一个不会使用文字&#34;第二个&#34;以及委托给约会者的UDF。
CREATE FUNCTION [dbo].[datediff_seconds]
(
@from datetime,
@to datetime
)
RETURNS int
AS
BEGIN
RETURN datediff(second, @from, @to)
END
GO
它是一种kludge,但有效。
答案 2 :(得分:0)
我最终只是简单地转换为unix_timestamp,这是数字并且可以进行差异化。遗憾的是,JPA无法为函数提供参数。
cb.greaterThan(
cb.diff(
cb.function("unix_timestamp", Long.class, root.get(Table_.until)),
cb.function("unix_timestamp", Long.class, root.get(Table_.from))
)
, 3600L*longerThanHours)