java 条件查询组合where方法中的和 predicate 和或 predicate

sxissh06  于 2023-01-29  发布在  Java
关注(0)|答案(2)|浏览(428)

标准生成器的where方法
根据指定的限制 predicate 的合取来限制查询结果
换句话说,用AND连接所有 predicate 。我以这种方式将 predicate 列表传递给此方法:

criteria.where(preds.toArray(new Predicate[0]));

结果查询如下所示:

... where p1 and p2 and p3

但是我需要的是

... where p1 and p2 or p3

我尝试使用两个 predicate 列表,一个用于“AND”,另一个用于“ORS”:

if(preds.isEmpty() && !orPreds.isEmpty()) {
    criteria.where(cb.or(orPreds.toArray(new Predicate[orPreds.size()])));
}
else if(!preds.isEmpty() && !orPreds.isEmpty()) {
    criteria.where(cb.and(preds.toArray(new Predicate[preds.size()])), 
    cb.or(orPreds.toArray(new Predicate[orPreds.size()])));
}
else {
    criteria.where(preds.toArray(new Predicate[0]));
}

但结果查询是相同的:

... where p1 and p2 and p3

你知道吗?

rxztt3cl

rxztt3cl1#

只需使用CriteriaBuilder.and(Predicate... restrictions)CriteriaBuilder.or(Predicate... restrictions)将 predicate 数组合并为简单 predicate
用于获取where (p1 and p2) or p3,其中p1p2p3都是与and语句连接的 predicate 数组:

Predicate[] p1 = new Predicate[2];
Predicate[] p2 = new Predicate[2];
Predicate[] p3 = new Predicate[2];
// add your predicates to the arrays.     
Predicate p1all = cb.and(p1);    
Predicate p2all = cb.and(p2);
Predicate p3all = cb.and(p3);
Predicate pFinal = cb.or(cb.and(p1all, p2all), p3all);
criteria.where(pFinal);

要获取where p1 and (p2 or p3)

Predicate pFinal = cb.and(cb.or(p2all, p3all), p1all);
criteria.where(pFinal);

最后,如果要通过将 predicate 数组与or语句连接来构建单个 predicate ,请使用以下代码:

Predicate p1all = cb.or(p1);
tpgth1q7

tpgth1q72#

默认情况下,所有 predicate 都被理解为“AND”。
您可以使用cb.和/ cb.or(如果需要,可以嵌套)“播放” predicate 以增加其复杂性
您可以创建如下列表:

Root<BeanA> queryRoot = cq.from(BeanA.class);

List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(queryRoot.get("id"), valueA);
predicates.add(cb.or(
                cb.equal(queryRoot.get("id"), valueA,
                cb.equal(queryRoot.get("id"), valueB
        ));
predicates.add(cb.and(
       cb.equal(queryRoot.get("valueC"), valueC),
       cb.or(
             cb.equal(queryRoot.get("id"), valueA,
             cb.equal(queryRoot.get("id"), valueB
        ))
);

cq.where(predicates.toArray(Predicate[]::new));

如果需要,也可以使用多选(如果要处理子查询的结果,请在此添加它们)

List<Selection> selectList = new ArrayList<>();

 selectList.add(queryRoot.get("id"));
 selectList.add(queryRoot.get("title"));

 cq.multiselect(selectList.toArray(Selection[]::new));

添加多选后,您可能需要orderBy。您可以遵循相同的概念,但使用表达式列表

List<Expression> groupByList = new ArrayList<>();

groupByList.add(proyectoJoin.get("id"));
groupByList.add(proyectoJoin.get("title"));
 
cq.groupBy(groupByList.toArray(Expression[]::new));

相关问题