java - CriteriaBuilder 连接/子查询与结果整数

标签 java jpa criteria-api

我正在尝试使用CriteriaBuilder 创建一个查询来选择库存大于零的所有Product。库存为 sum(DeliveryRow.amount) - sum(DispatchRow.amount)。当然,两者都只包含正确的产品

我尝试为 DeliveryRowDispatchRow 创建Subquery,尽管我觉得这应该使用 join() 来完成.

类(class)

Product { 
    (...)
}

DeliveryRow {
    @ManyToOne
    private Product product;

    private int amount;
}

DispatchRow {
    @ManyToOne
    private Product product;

    private int amount;
}

查询

在此查询中,我不确定如何处理 xxx。我尝试过进行子查询,但没有成功。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root product = query.from(Product.class);
query.select(product);

// sum of DeliveryRow.amount where DeliveryRow.product = Product
// minus 
// sum of DispatchRow.amount where DispatchRow.product = Product
Expression stock = xxx;  

query.where(cb.gt(stock, Integer.parseInt(0)));
return em.createQuery(query).getResultList();

关于如何解决这个问题有什么建议吗?

最佳答案

我最近一直在研究 JPA/JPQL,研究三种不同的检索实体的方法:NamedQueries、em.CreateQuery 和 CriteriaBuilder。我认为 CriteriaBuilder 是三者中最难用的。我建议创建一个 NamedQuery 来处理这种情况,它会更容易实现和阅读。

使用此 JPQL 表达式,您可以检索库存大于零的所有产品:

SELECT p.name, SUM(delRow.amount) - SUM(disRow.amount) 
FROM Product p join p.deliveryRows delRow join p.dispatchRows disRow
HAVING SUM(delRow.amount) - SUM(disRow.amount) > 0

/* This assumes product has a Collection<DispatchRow> named dispatchRows 
   and a Collection<DeliveryRow> named deliveryRows.
*/

使其成为“产品”实体中的命名查询

//This should be concatenated or on one line
@NamedQuery(name="Product.hasStock" 
    query="SELECT p.name, SUM(delRow.amount) - SUM(disRow.amount) 
    FROM Product p join p.deliveryRows delRow join p.dispatchRows disRow
    HAVING SUM(delRow.amount) - SUM(disRow.amount) > 0");

然后使用 EntityManager 执行此查询

@PersistenceContext
EntityManager em;

public void execute(){
  List<Object[]> products = 
      em.createNamedQuery("Product.hasStock").getResultList();

  /* Projections return a List<Object[]> where position 1 in the object array
     corresponds with the first field in the select statement, position two
     corresponds with the second field and so on...  These can also be strongly typed
     if an object is created and the constructor is specified in JPQL statement
  */
}

我知道这是与使用 Criteria API 不同的方法,但在我看来,JPQL 查询远远优于 Criteria API。与与 SQL 非常相似的 JPQL 语法相比,API 感觉不太简洁和直观。如果您决定采用此方法,我创建了一个视频教程,用于演示 @NamedQueries 并展示如何强类型化包含投影的查询结果。可以查到here .

关于java - CriteriaBuilder 连接/子查询与结果整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16498542/

相关文章:

java - "Spring Data - JPA"是 JPA 实现还是只是对另一个 JPA 实现的扩展?

java - 集成 Vaadin 7 和 EJB 的最佳方式或如何制作服务层?

java - JPQl 查询有错误

java - 如何在某些单元格上使用自定义操作的CriteriaQuery SUM?

Java Android Canvas.drawText(...) 在所有屏幕上同样大

java - Hibernate 5.2 和 Spring 4.3,非 JPA - javax.persistence.TransactionRequiredException : no transaction is in progress

hibernate - 使用 Criteriabuilder 查询对 Long 值进行通配符搜索

nhibernate - 如何使用 Criteria 或 QueryOver API 编写此 linq 查询

java - 将 JSONObject 放入 JSONArray 或相反将额外的反斜杠添加到 JSON 数组 - Android

java - 碧 Jade 报告 : JRBeanCollectionDataSource cannot be resolved to a type