[英]Using JPA Conjuction to write conditional statements - Criteria API
I need to replicate this query into JPA CriteriaBuilder code: 我需要将此查询复制到JPA CriteriaBuilder代码中:
....
WHERE (
(lower(userdto0_.city) LIKE '%istanbul%')
OR
(lower(userdto0_.city) LIKE '%ankara%')
)
AND
(lower(TO_CHAR(cast(user1_.id AS varchar(255)))) LIKE 1)
Here's the code; 这是代码;
public Page<UserDTO> findByCriteria(String sort, Pageable pageable, Map<String, List<String>> filtersMap) {
....
Root<UserDTO> iRoot = cq.from(UserDTO.class);
Join<UserDTO, User> bJoin = iRoot.join("user");
List<Predicate> predicates = new ArrayList<Predicate>();
cq.multiselect(bJoin.get("id"), bJoin.get("login"), bJoin.get("firstName"), bJoin.get("lastName"),
bJoin.get("dayOfBirth"), iRoot.get("district"), iRoot.get("city"));
filtersMap.entrySet().stream().filter(v -> v.getValue() != null && v.getValue().size() > 0).forEach(entry -> {
entry.getValue().forEach(k -> {
try {
bJoin.<String>get(entry.getKey()).as(String.class);
Expression<String> e1 = bJoin.<String>get(entry.getKey()).as(String.class);
Expression convertedColumnName = cb.function("TO_CHAR", String.class, e1);
predicates.add(cb.like(cb.lower(convertedColumnName), "%" + k.toLowerCase() + "%"));
} catch (Exception e) {
if (!k.isEmpty()) {
if (!iRoot.<String>get(entry.getKey()).getJavaType().toString().contains("String")) {
Expression<String> e1 = iRoot.<String>get(entry.getKey()).as(String.class);
Expression convertedColumnName = cb.function("TO_CHAR", String.class, e1);
predicates.add(cb.like(convertedColumnName, "%" + k + "%"));
} else {
predicates.add(
cb.like(cb.lower(iRoot.<String>get(entry.getKey())), "%" + k.toLowerCase() + "%"));
}
}
}
});
});
columnName = new ArrayList<String>();
filtersMap.entrySet().stream().distinct().filter(v -> v.getValue() != null && v.getValue().size() > 0 && !columnName.add(v.getKey())).forEach(entry -> {
for (int i = 0 ; i < filtersMap.size() ; i++) {
columnName.add(entry.getKey());
}
});
Predicate[] predArray = new Predicate[predicates.size()];
finalQuery = cb.disjunction();
columnName.forEach(name -> {
if (name.equals("city")) {
finalQuery = cb.or(predicates.toArray(predArray));
predicates.add(cb.or(predicates.toArray(predArray)));
cq.where(finalQuery);
} else {
predicates.toArray(predArray);
cq.where(predArray);
}
});
.....
}
But my sql looks like this with the code above; 但是我的sql上面的代码看起来像这样;
....
WHERE (lower(userdto0_.city) LIKE '%istanbul%')
OR (lower(userdto0_.city) LIKE '%ankara%')
AND (lower(TO_CHAR(cast(user1_.id AS varchar(255)))) LIKE 1)
Which gives a different result. 这给出了不同的结果。
I know I should use conjunction() and disjunction() methods but I'm new to JPA so I don't know how to use them to make the format proper. 我知道我应该使用joint()和disjunction()方法,但是我是JPA的新手,所以我不知道如何使用它们来使格式正确。
I solved the issue by adding cb.conjuction() 我通过添加cb.conjuction()解决了这个问题
My working code looks like this now; 我的工作代码现在看起来像这样;
public Page<UserDTO> findByCriteria(String sort, Pageable pageable, Map<String, List<String>> filtersMap) {
......
List<Predicate> predicatesOr = new ArrayList<Predicate>();
List<Predicate> predicatesAnd = new ArrayList<Predicate>();
cq.multiselect(bJoin.get("id"), bJoin.get("login"), bJoin.get("firstName"), bJoin.get("lastName"),
bJoin.get("dayOfBirth"), iRoot.get("district"), iRoot.get("city"));
filtersMap.entrySet().stream().filter(v -> v.getValue() != null && v.getValue().size() > 0).forEach(entry -> {
entry.getValue().forEach(k -> {
try {
bJoin.<String>get(entry.getKey()).as(String.class);
Expression<String> e1 = bJoin.<String>get(entry.getKey()).as(String.class);
Expression convertedColumnName = cb.function("TO_CHAR", String.class, e1);
if (entry.getValue().size() > 1) {
predicatesOr.add(cb.like(cb.lower(convertedColumnName), "%" + k.toLowerCase() + "%"));
}else {
predicatesAnd.add(cb.like(cb.lower(convertedColumnName), "%" + k.toLowerCase() + "%"));
}
} catch (Exception e) {
if (!k.isEmpty()) {
if (!iRoot.<String>get(entry.getKey()).getJavaType().toString().contains("String")) {
Expression<String> e1 = iRoot.<String>get(entry.getKey()).as(String.class);
Expression convertedColumnName = cb.function("TO_CHAR", String.class, e1);
if (entry.getValue().size() > 1) {
predicatesOr.add(cb.like(convertedColumnName, "%" + k + "%"));
}else {
predicatesAnd.add(cb.like(convertedColumnName, "%" + k + "%"));
}
} else {
if (entry.getValue().size() > 1) {
predicatesOr.add(cb.like(cb.lower(iRoot.<String>get(entry.getKey())), "%" + k.toLowerCase() + "%"));
}else {
predicatesAnd.add(cb.like(cb.lower(iRoot.<String>get(entry.getKey())), "%" + k.toLowerCase() + "%"));
}
}
}
}
});
});
Predicate[] predArrayOr = new Predicate[predicatesOr.size()];
Predicate[] predArrayAnd = new Predicate[predicatesAnd.size()];
predicatesOr.toArray(predArrayOr);
predicatesAnd.toArray(predArrayAnd);
finalQuery = cb.or(predArrayOr);
andQuery = cb.and(predArrayAnd);
Predicate pFinal = predArrayOr.length >= 2 ? cb.and(cb.or(finalQuery), andQuery) : cb.and(cb.or(cb.conjunction(), finalQuery), andQuery);
cq.where(pFinal);
......
}
This line; 这条线;
Predicate pFinal = predArrayOr.length >= 2 ? cb.and(cb.or(finalQuery), andQuery) : cb.and(cb.or(cb.conjunction(), finalQuery), andQuery);
works perfectly. 完美地工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.