[英]Criteria query combine and predicates and or predicates in where method
CriteriBuilder的where
方法
根据指定的限制谓词的合取来限制查询结果
换句话说,用 AND 连接所有谓词。 我以这种方式将谓词列表传递给此方法:
criteria.where(preds.toArray(new Predicate[0]));
结果查询是这样的:
... where p1 and p2 and p3
但是我需要的是:
... where p1 and p2 or p3
我尝试使用两个预测列表,一个用于“ANDS”,另一个用于“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
任何的想法?
只需使用CriteriaBuilder.and(Predicate... restrictions)
和CriteriaBuilder.or(Predicate... restrictions)
将谓词数组组合为简单谓词
为了获得where (p1 and p2) or p3
,其中p1
, p2
和p3
都是与and
语句连接的谓词数组:
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);
最后,如果要通过将谓词数组与or
语句连接来构建单个谓词,请使用以下命令:
Predicate p1all = cb.or(p1);
默认情况下,所有谓词都被理解为“AND”。
您可以“玩”使用 cb.and / cb.or 为谓词增加更多复杂性(如果需要嵌套)
您可以像这样创建一个列表:
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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.