我正在尝试使用CriteriaBuilder
创建一个查询,以选择库存大于零的所有Product
。库存是sum(DeliveryRow.amount) - sum(DispatchRow.amount)
。两个都只包含权利Product
。
我尝试为Subquery
和DeliveryRow
创建DispatchRow
,但我觉得应该使用join()
来完成。
类
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();
有关如何解决此问题的任何建议?
答案 0 :(得分:0)
我最近一直在研究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。与JPQL语法相比,它与SQL非常相似,API不那么简洁直观。如果您决定采用此路线,我已创建了一个演示@NamedQueries
的视频教程,并演示了如何强力键入包含投影的查询结果。它可以找到here。