Spring boot 是否可以分组谓词或有条件地使用'in'
Spring boot Is it possible to group predicates or use 'in' conditionally
我在使用 CriteriaBuilder
和 Predicates
对查询进行正确分组时遇到问题。
我想创建一个可以生成如下内容的查询:
SELECT * from tableName where columnA = '1234' and (columnB Like '%33%' or columnB Like '%44%')
但我得到的(显然是预期的代码)是:
SELECT * from tableName where columnA = '1234' and columnB Like '%33%' or columnB Like '%44%'
这不会产生与第一个查询相同的结果。
一直在尝试解决它,但这是我第一次使用 criteriaBuilder 和谓词。
这是代码:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Foo> criteriaQuery = builder.createQuery(Foo.class);
Root r = criteriaQuery.from(Foo.class);
Predicate predicate = builder.conjunction();
for(Map.Entry<String, String> entry : searchParams.entrySet()){
if((entry.getKey().equalsIgnoreCase("columnK") || entry.getKey().equalsIgnoreCase("columnY") ||
entry.getKey().equalsIgnoreCase("columnZ") || entry.getKey().equalsIgnoreCase("columnJ")) && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate,
builder.like(r.get(entry.getKey()),
String.format("%%%s%%", entry.getValue().toString())));
}
else if(entry.getKey().equalsIgnoreCase("theDate") && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate, builder.equal(r.get(entry.getKey()), entry.getValue()));
}
}
//here's where the problem is ... I realize I can use IN, but I also didn't get that to work
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
criteriaQuery.where(predicate);
谢谢。
好的,所以我在仔细阅读这个答案后才破解了这个问题这个解决方案并不完全是我需要的,但它帮助了...很多
我创建了一条路径并将其与我的谓词组合。
更改内容如下:
这个:
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
变成了:
Path<Object> path = r.get("acceptorId");
CriteriaBuilder.In<Object> in = builder.in(path);
for (String oneId: idStringList) {
in.value(oneId);
}
predicate = builder.and(predicate, in);
虽然我解决了所有的麻烦,但非常简单。
希望这对其他人也有帮助!
我在使用 CriteriaBuilder
和 Predicates
对查询进行正确分组时遇到问题。
我想创建一个可以生成如下内容的查询:
SELECT * from tableName where columnA = '1234' and (columnB Like '%33%' or columnB Like '%44%')
但我得到的(显然是预期的代码)是:
SELECT * from tableName where columnA = '1234' and columnB Like '%33%' or columnB Like '%44%'
这不会产生与第一个查询相同的结果。
一直在尝试解决它,但这是我第一次使用 criteriaBuilder 和谓词。 这是代码:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Foo> criteriaQuery = builder.createQuery(Foo.class);
Root r = criteriaQuery.from(Foo.class);
Predicate predicate = builder.conjunction();
for(Map.Entry<String, String> entry : searchParams.entrySet()){
if((entry.getKey().equalsIgnoreCase("columnK") || entry.getKey().equalsIgnoreCase("columnY") ||
entry.getKey().equalsIgnoreCase("columnZ") || entry.getKey().equalsIgnoreCase("columnJ")) && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate,
builder.like(r.get(entry.getKey()),
String.format("%%%s%%", entry.getValue().toString())));
}
else if(entry.getKey().equalsIgnoreCase("theDate") && !Strings.isNullOrEmpty(entry.getValue())){
predicate = builder.and(predicate, builder.equal(r.get(entry.getKey()), entry.getValue()));
}
}
//here's where the problem is ... I realize I can use IN, but I also didn't get that to work
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
criteriaQuery.where(predicate);
谢谢。
好的,所以我在仔细阅读这个答案后才破解了这个问题这个解决方案并不完全是我需要的,但它帮助了...很多
我创建了一条路径并将其与我的谓词组合。
更改内容如下:
这个:
boolean isFirstDone = false;
for(String oneId: idStringList){
if(!isFirstDone) {
predicate = builder.and(predicate, builder.equal(r.get("acceptorId"), oneId));
isFirstDone = true;
}
else{
predicate = builder.or(predicate, builder.equal(r.get("acceptorId"), oneId));
}
}
变成了:
Path<Object> path = r.get("acceptorId");
CriteriaBuilder.In<Object> in = builder.in(path);
for (String oneId: idStringList) {
in.value(oneId);
}
predicate = builder.and(predicate, in);
虽然我解决了所有的麻烦,但非常简单。
希望这对其他人也有帮助!