简体   繁体   English

使用JPA联合编写条件语句-Criteria API

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM