[英]Dynamic Query JPA 2 Specification With CriteriaBuilder
我有下表数据:
Product Reason Qty
Pepsi IN 10
Pepsi Out 2
Pepsi In 15
Pepsi Out 5
Coke IN 100
Coke Out 20
Coke In 35
Coke Out 25
Fanta Out 55
我想获得如下结果:
Product Qty
Pepsi 18
Coke 90
Fanta -55
因为我有以下查询:
SELECT Product,
SUM(CASE WHEN reason IN ('IN','REFUND') THEN Qty
WHEN reason IN ('OUT','WASTE') THEN -Qty
ELSE NULL END) AS Qty
FROM stock
GROUP BY Product;
我想使用像这个链接中使用的JPA Specification
,我是JPA Specification
新手,有人可以指导我吗?
我有这个链接和这个链接,但我不确定解决问题的正确问题是什么?
编辑:
我试过下面的代码
@Override
public Predicate toPredicate(Root<Stockdiary> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Path reasonexpression = root.get("reason");
Path qtyexpression = root.get("qty");
List<String> inList = new ArrayList<String> ();
inList.add("IN");
List<String> outList = new ArrayList<String> ();
outList.add("OUT");
Predicate inpredicate = reasonexpression.in(inList);
Predicate outpredicate = reasonexpression.in(outList);
Expression<Number> sum = builder.sum(
builder.<Number>selectCase()
.when(inpredicate,qtyexpression.as(Double.class))
.when(outpredicate,builder.neg(qtyexpression).as(Double.class))
.otherwise(0));
return builder.equal(sum.as(Integer.class), 1)
}
从可分页的方式调用它
Page<Stockdiary> page = stockRepository.findAll(spec,pageable);
以下查询: -
select count(stock0_.stock_id) as col_0_0_ from stock stock0_ cross join session_tbl session_tb1_
where stock0_.session_id=session_tb1_.session_id and
cast(sum(case when stock0_.reason in (?) then stock0_.qty when stock0_.reason in (?) then -stock0_.qty else 101 end) as signed)=1
group by stock0_.reason , stock0_.products_id , session_tb1_.terminal_id
由于case
语句在where
子句之后where
我得到SQL Exception。 我不知道为什么spring把case
放在where
子句之后。
我正在尝试进行动态查询,因为我无法使用静态查询。
基本上,您正在寻找执行本机查询 。
特别是,您可以使用JPA功能SqlResultSetMapping
来定义本机查询与可以保存数据的DTO对象之间的映射。
假设您的需求的DTO如下所示:
class ProductQuantity {
private String product;
private Integer quantity;
public ProductQuantity(String product, Integer quantity) {
this.product = product;
this.quantity = quantity;
}
public getProduct() { return this.product; }
public getQuantity() { return this.quantity; }
}
以下定义可以充当本机查询的映射:
@SqlResultSetMapping(
name = "ProductQuantityMapping",
classes = @ConstructorResult(
targetClass = ProductQuantity.class,
columns = {
@ColumnResult(name = "product", type = String.class),
@ColumnResult(name = "qty", type = Integer.class)
})
)
最后,查询可以调用为:
Query q = entityManager.createNativeQuery("SELECT Product,SUM(CASE WHEN reason IN ('IN','REFUND') THEN Qty WHEN reason IN ('OUT','WASTE') THEN -Qty ELSE NULL END) AS Qty FROM stock GROUP BY Product");
List<ProductQuantity> result = q.getResultList();
for(ProductQuantity pq : result) {
System.out.println("product: " + pq.getProduct() + ", Quantity: " + pq.getQuantity());
}
有关更多信息/示例,请查看本文 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.