JPA CriteriaQuery计算日期时间差以在谓词中使用 [英] JPA CriteriaQuery calculating datetime difference for use in where predicate

查看:849
本文介绍了JPA CriteriaQuery计算日期时间差以在谓词中使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从数据库中选择两个字段之间的时差小于或大于某个值的实体.在标准SQL中,只需使用TIMESTAMPDIFF函数即可完成此操作:

I am trying to select entities from my database that have a time difference between 2 fields less than or greater to some value. In standard SQL, this is simply accomplished using the TIMESTAMPDIFF function:

SELECT * from run where TIMESTAMPDIFF(SECOND, run.end_time, run.start_time) > 60;

但是,JPA 2.0中似乎没有任何等效的东西.

However, there doesn't seem to be any equivalent in JPA 2.0.

我已经尝试了所有我能想到的一切,包括这里的建议:

I've tried everything I can think of, including the suggestions here: Using TIMESTAMPDIFF with JPA criteria query and hibernate as the provider

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天.还有其他方法可以做到这一点吗?

simply doesn't work and since I am specifically trying to calculate large durations (60/90 days). The TIMEDIFF solution doesn't help because the max TIMEDIFF that can be returned is 35 days. Is there some other way to accomplish this?

推荐答案

以下是

SELECT *从运行中TIMESTAMPDIFF(SECOND,run.end_time, run.start_time)> 60;

SELECT * from run where TIMESTAMPDIFF(SECOND, run.end_time, run.start_time) > 60;

首先,您必须创建单位表达式并将其从BasicFunctionExpression扩展,对于该表达式,将"SECOND"参数作为单位并仅覆盖其rendor(RenderingContext renderingContext)方法.

First you have to create unit expression and extend it from BasicFunctionExpression for which take "SECOND" parameter as a unit and override its rendor(RenderingContext renderingContext) method only.

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条件查询中使用此单位表达式.

then you use this unit expression in your JPA criteria Query.

    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计算日期时间差以在谓词中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆