JPA CriteriaBuilder 将合取条件转换为析取条件

问题描述 投票:0回答:2

我需要将此查询复制到 JPA CriteriaBuilder 代码中:

....
where
     article.client_id = 1 
     and article.price > 0
     and (
           article.code like '%this is statement%' 
           or article.oem_code like '%this is statement%'
           or ( 
               article.description like '%this%'
               and article.description like '%is%'
               and article.description like '%statement%'
           )    
     )

这是我的代码:

...

Root<Article> article = cq.from(Article.class);

List<Predicate> predicates = new ArrayList<Predicate>();

predicates.add(cb.equal(article.get(Article_.clientId), filter.getClientId()));

predicates.add(cb.greaterThan(article.get(Article_.price), BigDecimal.ZERO));

String searchQuery = filter.getSearchQuery();

Predicate disjunction = cb.disjunction();

disjunction.getExpressions().add(cb.like(article.get(Article_.code), "%" + searchQuery + "%"));
disjunction.getExpressions().add(cb.like(article.get(Article_.oem_code), "%" + searchQuery + "%"));

List<Predicate> andPredicate = new ArrayList<Predicate>();

for (String str : searchQuery.split(" ")) {
   andPredicate.add(cb.like(article.get(Article_.description), "%" + str + "%"));    
}

现在,如何将这个

andPredicate
添加到我的析取谓词中?
getExpressions().add(...)
不采用
Predicate
作为参数。

谢谢

java hibernate jpa criteria
2个回答
18
投票

这就是我所做的,看起来效果很好:

...  
Predicate pr1 = cb.like(article.get(Article_.code), "%" + searchQuery + "%");
Predicate pr2 = cb.like(article.get(Article_.oem_code), "%" + searchQuery + "%");
Predicate pr3 = cb.conjunction();

for (String str : busquedaSplit) {
    Predicate newPredicate = cb.like(article.get(Article_.description), "%" + str + "%");
    pr3 = cb.and(pr3, newPredicate);
}

disjunction = cb.or(pr1, pr2, pr3);

predicates.add(disjunction);

0
投票

请注意,对于 JPA 3 Criteria API

Predicate.getExpressions().add(...)
将不起作用。它确实可以在 Hibernate 5 Criteria API 中工作(很多人,包括我,都使用过它) - 但在 Hibernate 6 中,不再支持 Criteria API - 这样的代码将停止工作。

例如,Spring Boot 3 使用 JPA 3 Criteria API。

底行代码如上面引用的:

disjunction.getExpressions().add(cb.like(article.get(Article_.code), "%" + searchQuery + "%"));

disjunction.getExpressions().add(cb.like(article.get(Article_.oem_code), "%" + searchQuery + "%"));

..根本不会修改析取谓词。

关于组合和/或谓词的良好描述在这里:https://www.baeldung.com/jpa-and-or-criteria-predicates

无论您使用什么版本的 CriteriaAPI,这都有效。`

© www.soinside.com 2019 - 2024. All rights reserved.