Spring Data에서 Query method만으로는 모든 쿼리를 커버할 순 없다.
Specification을 이용한 조건쿼리 생성하는 방법에 대해 알아보자.
명세 기능을 사용하려면 아래와 같이 JpaSepcificationExecutor 인터페이스를 상속 받으면 된다.1
2
3public interface OrderRepository extends JpaRepository<Order, Long>, JpaSpecificationExecuter<Order> {
}
명세를 정의하려면 Specification 인터페이스의 toPredicate() 메소드를 구현하면 된다.
사용그룹에 따라 다르겠지만, 딱히 정해져있지 않다면 명세는 repository 패키지에 넣어 두어도 좋겠다.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class OrderSpecification {
public static Specification<Order> memberName(final String memberName) {
return new Specification<Order>() {
public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
if(StringUtils.isEmpty(memberName)) return null;
Join<Order, Member> m = root.join("member", JoinType.INNER);
return builder.equal(m.get("name"), memberName);
}
}
}
public static Specification<Order> isOrderStatus(final String memberName) {
return new Specification<Order>() {
public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return builder.equal(root.get("status"), OrderStatus.ORDER);
}
};
}
}
아래는 명세를 사용하는 코드이다.1
2
3
4public List<Order> findOrders(String name) {
List<Order> result = OrderRepository.findAll(where(memberName(name)).and(isOrderStatus()));
return result;
}
Reference : 자바 ORM 표준 JPA 프로그래밍