ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JPA 다중 검색, criteriaBuilder
    카테고리 없음 2022. 10. 24. 17:42
    반응형

    jpa사용해서 멀티 검색 하기 까다롭다.

    그럴때 사용하면 좋을 Criteriabuilder

     

    public Page<T> exampleCriteria(JpaSpecificationExecutor<T> executor,
            final List<Triple<String, String, Object>>criteriaList, Pageable pageable) {
    
            Page<T> findResult = executor.findAll(new Specification<T>() {
    
                @Override
                public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
    
                    List<Predicate> stringPredicateList = new ArrayList<Predicate>();
                    List<Predicate> numPredicateList = new ArrayList<Predicate>();
                    List<Predicate> pairPredicates = new ArrayList<Predicate>();
    
                    for (Triple<String, String, Object> criteriaItem : criteriaList) {
    
                        if(criteriaItem.getRight() instanceof String) {
                            String fieldName = criteriaItem.getLeft();
                            String operation = criteriaItem.getMiddle();
                            String keywordEq = (String) criteriaItem.getRight();
                            String keyword =  ((String) criteriaItem.getRight()).replace("%","\\%").replace("_","\\_");
    
                            if ("eq".equals(operation)) {
                                stringPredicateList.add(criteriaBuilder.and(criteriaBuilder.equal(root.get(fieldName), keywordEq)));
    
                            }else if("like".equals(operation)){ 
                                stringPredicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get(fieldName).as(String.class), "%"+keyword +"%")));
    
                            }else if("forward_match".equals(operation)){ 
                                stringPredicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get(fieldName).as(String.class), keyword +"%")));
    
                            }else if("backward_match".equals(operation)){ 
                                stringPredicateList.add(criteriaBuilder.and(criteriaBuilder.like(root.get(fieldName).as(String.class), "%"+keyword)));
    
                            }
    
                        }else if(criteriaItem.getRight() instanceof List) {
                            String fieldName = criteriaItem.getLeft();
                            String operation = criteriaItem.getMiddle();
                            @SuppressWarnings("unchecked")
                            List<Double> keyword = (List<Double>) criteriaItem.getRight();
    
                            if ("greater".equals(operation)) {
                                numPredicateList.add(criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(root.get(fieldName),keyword.get(0))));
    
                            }else if("less".equals(operation)){ 
                                numPredicateList.add(criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(root.get(fieldName),keyword.get(0))));
    
                            }else if("between".equals(operation)){ 
                                numPredicateList.add(criteriaBuilder.and(criteriaBuilder.between(root.get(fieldName),keyword.get(0),keyword.get(1))));
                            }
    
                        }else if(criteriaItem.getRight() == null) {
                            pairPredicates.add(criteriaBuilder.equal(root.get(criteriaItem.getLeft()), criteriaItem.getMiddle()));
                        }
                    }
    
                    Predicate pairPredicate = criteriaBuilder.and(pairPredicates.toArray(new Predicate[pairPredicates.size()]));
    
                    if (stringPredicateList.size() > 0 && numPredicateList.size() == 0) {
                        Predicate triplePredicateString = criteriaBuilder.or(stringPredicateList.toArray(new Predicate[stringPredicateList.size()]));
                        return criteriaBuilder.and(criteriaBuilder.and(pairPredicate), triplePredicateString);
    
                    }else if(stringPredicateList.size() > 0 && numPredicateList.size() > 0) {
                        Predicate triplePredicateString = criteriaBuilder.or(stringPredicateList.toArray(new Predicate[stringPredicateList.size()]));
                        Predicate triplePredicateNum = criteriaBuilder.or(numPredicateList.toArray(new Predicate[numPredicateList.size()]));
                        return criteriaBuilder.and(criteriaBuilder.and(pairPredicate), triplePredicateString,triplePredicateNum);
    
                    }else if(stringPredicateList.size() == 0 && numPredicateList.size() > 0) {
                        Predicate triplePredicateNum = criteriaBuilder.or(numPredicateList.toArray(new Predicate[numPredicateList.size()]));
                        return criteriaBuilder.and(criteriaBuilder.and(pairPredicate), triplePredicateNum);
    
                    }else {
                        return criteriaBuilder.and(pairPredicate);
                    }
    
                }
            },pageable);
    
            return findResult;
        }

     

    or 조건과 and 조건을 조작하려면 criteriaBuilder.or 이부분을 and 로 변경해준다.

     Predicate triplePredicateString = criteriaBuilder.or(stringPredicateList.toArray(new Predicate[stringPredicateList.size()]));

     

     

     

    combining JPA and/or criteria predicates

    참고하면 좋을 사이트 : https://www.baeldung.com/jpa-and-or-criteria-predicates

    반응형

    댓글

Designed by Tistory.