[英]Dynamic Query JPA 2 Specification With CriteriaBuilder
I have below table data: 我有下表数据:
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
and I want to get result like below: 我想获得如下结果:
Product Qty
Pepsi 18
Coke 90
Fanta -55
for that I have got below query: 因为我有以下查询:
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;
I want to use JPA Specification
like used in this link , I am new to JPA Specification
can someone please guide me? 我想使用像这个链接中使用的JPA Specification
,我是JPA Specification
新手,有人可以指导我吗?
I have got this link and this link but I am not sure what is the correct question to solve the problem? 我有这个链接和这个链接,但我不确定解决问题的正确问题是什么?
EDIT: 编辑:
I have tried below code 我试过下面的代码
@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)
}
Call it from as pageable 从可分页的方式调用它
Page<Stockdiary> page = stockRepository.findAll(spec,pageable);
which is making below query :- 以下查询: -
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
I am getting SQL Exception due to case
statement is after where
clause. 由于case
语句在where
子句之后where
我得到SQL Exception。 I dont know why spring put case
after the where
clause. 我不知道为什么spring把case
放在where
子句之后。
I am trying to make dynamic query, as i cant use static query. 我正在尝试进行动态查询,因为我无法使用静态查询。
Essentially you are looking to perform a Native Query . 基本上,您正在寻找执行本机查询 。
In particular, you could use the JPA feature SqlResultSetMapping
to define the mapping between your native query and the DTO object that can hold your data. 特别是,您可以使用JPA功能SqlResultSetMapping
来定义本机查询与可以保存数据的DTO对象之间的映射。
Assuming the DTO for your needs looks like this: 假设您的需求的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; }
}
The following definition can act as a mapping for the native query: 以下定义可以充当本机查询的映射:
@SqlResultSetMapping(
name = "ProductQuantityMapping",
classes = @ConstructorResult(
targetClass = ProductQuantity.class,
columns = {
@ColumnResult(name = "product", type = String.class),
@ColumnResult(name = "qty", type = Integer.class)
})
)
And finally the query can be invoked as: 最后,查询可以调用为:
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());
}
For more information/examples take a look at this article . 有关更多信息/示例,请查看本文 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.