0

假设我有以下实体:

@Entity
@Table(name="ORDER_ITEM")
public class Order {

    @Id
    @Column(name = "ORDER_ID")
    private Long id;

    @Column(name = "ORDER_VALUE")
    private BigDecimal value;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "M-")
    @Column(name = "CREATED_AT", columnDefinition = "date")
    private Date createdAt;

    @Column(name = "HOURS_MAX")
    private Integer hoursMax = 24;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public BigDecimal getValue() {
        return value;
    }

    public void setValue(BigDecimal value) {
        this.value = value;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Integer getHoursMax() {
        return hoursMax;
    }

    public void setHoursMax(Integer hoursMax) {
        this.hoursMax = hoursMax;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", value=" + value +
                ", createdAt=" + createdAt +
                ", hoursMax=" + hoursMax +
                '}';
    }
}

因此,我需要在 hoursMax 整数字段的周期最大值中通过 createAt 日期字段对订单限制进行条件查询。我看到很多使用 Date 实例 java 减去整数文字值(以小时为单位)的示例,如下例所示:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Order> cq = cb.createQuery(Order.class);
    Root<Order> orderRoot = cq.from(Order.class);

    Calendar c = Calendar.getInstance();
    c.add(Calendar.HOUR_OF_DAY, -24);

     cq.select(orderRoot).where(
            cb.greaterThan(orderRoot.get(Order_.createdAt) ,c.getTime())
     );

    TypedQuery<Order> query = em.createQuery(cq);
    List<Order> result = query.getResultList();

但是,在这种情况下,我需要使用代表这个最大周期的字段 hoursMax 我应该放入什么????以下 ?

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Order> cq = cb.createQuery(Order.class);
    Root<Order> orderRoot = cq.from(Order.class);

    cq.select(orderRoot).where(
            cb.greaterThan(orderRoot.get(Order_.createdAt) , ??? )
    );

    TypedQuery<Order> query = em.createQuery(cq);
    List<Order> result = query.getResultList();

注意:另外,我想避免对 hoursMax 执行额外的预查询。

4

1 回答 1

0

好吧,我找到了解决方法,但是我不知道是否有更好的解决方案,因为它使实现依赖于特定于数据库的提供程序。

在这种情况下,我使用了 hibernate 中的 @Formula,如下例所示。

注意:我省略了 GETTERS 和 SETTERS 只是为了简化答案。

对于 h2 数据库。

@Entity
@Table(name="ORDER_ITEM")
public class Order {

    @Id
    @Column(name = "ORDER_ID")
    private Long id;

    @Column(name = "ORDER_VALUE")
    private BigDecimal value;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "M-")
    @Column(name = "CREATED_AT", columnDefinition = "date")
    private Date createdAt;

    @Column(name = "HOURS_MAX")
    private Integer hoursMax = 24;

    @Formula("DATEADD('HOUR',HOURS_MAX *(-1), CURRENT_DATE())")
    private Date createSinceLimitHours;

}

对于 Oracle 数据库并不是那么简单,因为还没有 Oracle 11g 方言:查看它以获取更多信息:https ://stackoverflow.com/a/32019401/1488761

最后,只需使用新字段制定标准:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> orderRoot = cq.from(Order.class);

cq.select(orderRoot).where(
        cb.greaterThan(orderRoot.get(Order_.createdAt) , orderRoot.get(Order_.createSinceLimitHours))
);

TypedQuery<Order> query = em.createQuery(cq);
List<Order> result = query.getResultList();
于 2015-08-13T21:54:43.330 回答