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