JPA

JPA Secification을 이용한 검색

Beekei 2022. 1. 20. 14:38
반응형

Spring Data JPA는 org.springframework.data.jpa.domain.Specification 클래스로 다양한 검색조건을을 조립해서 새로운 검색조건을 만들 수 있다.

 

본래에 JpaRepository 상속받을때 JpaSpecificationExecutor을 상속받으면 된다.

public interface JpaSpecificationExecutor<T> {
    T findOn(Specification<T> spec);
    List<T> findAll(Specification<T> spec);
    Page<T> findAll(Specification<T> spec, Pageable pagaable);
    List<T> findAll(Specification<T> spec, Sort sort);
    long count(Specification<T> spec);
}
public interface OrderRepository extends JpaRepository<Order, Long>, JpaSpecificationExecutor<Order> {
   ...
}

public List<Order> findOrders(String name) {
    List<Order> result = orderRepository.findAll(where(memberName(name)).and(isOrderStatus()));
    return result;
}
public class OrderSpec {
    
    public static Specification<Order> memberName(final String memberName) {
        return new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                if (StringUtils.isBlank(memberName)) return null;
                Join<Order, Member> m = root.join("member", JoinType.INNER); // 회원과 JOIN
                return criteriaBuilder.equal(m.get("name", memberName));
            }
        }
    }
    
    public static Specification<Order> isOrderStatus() {
        return new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.equal(root.get("status", OrderStatus.ORDER));
            }
        }
    }
    
}

Specifications는 조건식들을 조립할 수 있도록 도와주는 클래스인데 where, and, or, not 메소드를 제공한다.

이 기능을 사용할때 static 함수를 사용하면 더욱 읽기 쉬운 코드가 된다.

 

나는 검색을 사용하는 목록 조회 시에는 거의 QueryDSL을 사용하므로 해당 기능은 별로 사용한 적이 없다...

반응형