: 스프링 데이터 JPA는 검색 조건을 표현하기 위한 인터페이스인 Specification을 제공하며 다음과 같이 구현되어 있다.
public interface Specification<T> extends Serializable {
// not, where, and, or 메서드 생략
@Nullable
Predicate toPredicate(Root<T> root, CriteriaQuery query, CriteriaBuilder cb);
}
Java
복사
: 스펙 인터페이스에서 지네릭 타입 파라미터 T는 JPA 엔티티 타입을 의미한다. toPredicate() 메서드는 JPA 크리테리아 API에서 조건을 표현하는 Predicate를 생성한다.
: 예를 들어 다음과 같은 조건에 해당하는 스펙을 아래와 같이 구현할 수 있다.
•
엔티티 타입이 OrderSummary다.
•
ordererId 프로퍼티 값이 지정한 값과 동일하다.
public class OrdererldSpec implements Specification<OrderSummary> {
private String ordererld;
public OrdererIdSpec(String ordererld) {
this.ordererld = ordererld;
}
@Override
public Predicate toPredicate(Root<OrderSummary> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.equal(root.get(OrderSummary_.ordererId), ordererld);
}
}
Java
복사
: 스펙 구현 클래스를 개별적으로 만들지 않고 별도 클래스에 스펙 생성 기능을 모아도 된다. OrderSummary와 관련된 스펙 생성 기능을 다음과 같이 한 클래스에 모을 수 있다.
public class OrderSummarySpecs {
public static Specification<OrderSummary> ordererId(String ordererld) {
return (Root<OrderSummary> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> cb.equal(root.<String>get("ordererld"), ordererld);
}
public static Specification<OrderSummary> orderDateBetween( LocalDateTime from, LocalDateTime to) {
return (Root<OrderSummary> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> cb.between(root.get(OrderSummary_.orderDate), from, to);
}
}
Java
복사
: 이는 다음과 같이 사용될 수 있다.
Specification<OrderSummary> betweenSpec = OrderSummarySpecs.orderDateBetwwen(from, to);
Java
복사