【问题标题】:Using Projections in JPA 2在 JPA 2 中使用投影
【发布时间】:2012-04-05 20:37:45
【问题描述】:

我需要像下面这样转换 Hibernate 条件查询

curList = session.createCriteria(Islem.class)
                    .createAlias("workingDay", "d")
                    .setProjection(Projections.sum("amount"))
                    .add(Restrictions.eq("currency", CURRENCY))
                    .add(Restrictions.eq("product", product))
                    .add(Restrictions.ne("status", INACTIVE))
                    .add(Restrictions.eq("d.status", ACTIVE))
                    .getResultList();

但是在 JPA (2) 中,我不知道如何实现投影 - 在这种情况下 - 总和。奇怪的是,Hibernate 和 JPA(甚至是 Hibernate JPA 2)有如此巨大的差异,尤其是在标准查询中。

我开始

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Islem> cq = cb.createQuery(Islem.class);
Root<Islem> isr = cq.from(Islem.class);
cq.select(isr).where(cb.equal(isr.get("currency"), CURRENCY), 
                     cb.notEqual(isr.get("status"), INACTIVE),
                     cb.equal(isr.get("product"), product));

但是不知道如何在这里实现投影,也没有别名

【问题讨论】:

    标签: hibernate jpa-2.0 projection criteria-api hibernate-criteria


    【解决方案1】:

    这是一个老问题,但让我们举个例子:

    使用CriteriaBuilder,与Hibernate 不同,您总是从想要查询的结果类型开始,然后构造投影。

    CriteriaBuilder cb = em.getCriteriaBuilder();
    //We want Integer result
    CriteriaQuery<Integer> cq = cb.createQuery(Integer.class);
    
    //The root does not need to match the type of the result of the query!
    Root<Islem> isr = cq.from(Islem.class);
    
    //Create a join to access the variable status of working day
    Join<Islem,WorkingDay> join = isr.join("workingDay",JoinType.INNER);
    
    //Create the sum expression
    Expression<Integer> sum = cb.sum(isr.get("amount"));
    
    cq.where(
             cb.equal(isr.get("currency"), CURRENCY),
             cb.notEqual(isr.get("status"), INACTIVE),
             cb.equal(isr.get("product"), product),
             cb.equal(join.get("status"), ACTIVE)
    ).select(sum);
    

    另一方面,如果您想查询实际的“金额”值,您可以这样做:

    CompoundSelection<Integer> projection = cb.construct(Integer.class, cb.sum(isr.get("amount")));
    
    cq.where(..).select(projection);
    
    List<Integer> amounts = em.createQuery(cq).getResultList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-30
      • 2018-11-25
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 2021-10-29
      相关资源
      最近更新 更多