JPA CriteriaQuery计算日期时间差以在何处谓词中使用
我试图从数据库中选择两个字段之间的时差小于或大于某个值的实体。在标准SQL中,只需使用TIMESTAMPDIFF函数即可完成此操作:
SELECT * from run where TIMESTAMPDIFF(SECOND, run.end_time, run.start_time) > 60;
但是,JPA 2.0中似乎没有任何等效的东西。
我已经尝试了所有我能想到的一切,包括这里的建议:将TIMESTAMPDIFF与JPA条件查询一起使用,并将休眠作为提供者
predicate.getExpressions().add(criteriaBuilder.greaterThanOrEqualTo(criteriaBuilder.function("TIMESTAMPDIFF", Long.class, criteriaBuilder.literal("SECOND"), root.get(Run_.endTime), root.get(Run_.startTime)), minSeconds))
根本不起作用,因为我专门尝试计算长时间(60/90天)。TIMEDIFF解决方案无济于事,因为可以返回的最大TIMEDIFF为35天。还有其他方法可以做到这一点吗?
回答:
这是等效的JPA标准查询的说明
SELECT * from TIMESTAMPDIFF(SECOND,run.end_time,run.start_time)> 60的运行;
首先,您必须创建单位表达式并对其进行扩展BasicFunctionExpression
,以“
SECOND”参数为单位并rendor(RenderingContext renderingContext)
仅覆盖其方法。
import java.io.Serializable;import org.hibernate.query.criteria.internal.CriteriaBuilderImpl;
import org.hibernate.query.criteria.internal.compile.RenderingContext;
import org.hibernate.query.criteria.internal.expression.function.BasicFunctionExpression;
public class UnitExpression extends BasicFunctionExpression<String> implements Serializable {
public UnitExpression(CriteriaBuilderImpl criteriaBuilder, Class<String> javaType,
String functionName) {
super(criteriaBuilder, javaType, functionName);
}
@Override
public String render(RenderingContext renderingContext) {
return getFunctionName();
}
}
那么您可以在JPA条件查询中使用此单位表达式。
CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery<Run> cq = cb.createQuery(Run.class);
Root<Run> root = cq.from(Run.class);
Expression<String> second = new UnitExpression(null, String.class, "SECOND");
Expression<Integer> timeDiff = cb.function(
"TIMESTAMPDIFF",
Integer.class,
second,
root.<Timestamp>get(Run_.endTime),
root.<Timestamp>get(Run_.startTime));
List<Predicate> conditions = new ArrayList<>();
conditions.add(cb.greaterThan(timeDiff, 60));
cq.where(conditions.toArray(new Predicate[]{}));
return session.createQuery(cq);
这是工作。
以上是 JPA CriteriaQuery计算日期时间差以在何处谓词中使用 的全部内容, 来源链接: utcz.com/qa/416257.html