[ ddd start! ] 5. 리포지터리의 조회 기능

박병찬·2022년 2월 27일
0

ddd start

목록 보기
5/11
post-thumbnail

CHAPTER 5. 리포지터리의 조회 기능(JPA 중심)

1. 검색을 위한 스펙

  • 리포지토리는 애그리거트의 저장소이다. 애그리거트를 찾을 때 식별자를 이용하는 것이 기본이지만 식별자 외에 여러 다양한 조건으로 애그리거트를 찾아야 할 때가 있다.
  • 검색 조건의 조합이 다양할 경우 스펙을 이용해서 문제를 풀어야 한다.
public interface Speficiation<T> {
  public boolean isSatisfiedBy(T agg);
}
  • 스펙은 애그리거트가 특정 조건을 충족하는지 여부를 검사한다.
public class OrderSpec implements Specification<Order> {
  private String orderId;
  public OrderSpec(String ordererId) {
    this.ordererId = ordererId;
  }
  public boolean isSatisfiedBy(Order agg) {
    return agg.getOrdererId().getMemberId().getId().equals(ordererId);
  }
}
  • 리포지토리는 스펙을 전달받아 애그리거트를 걸러내는 용도로 사용한다.

만약 리포지토리가 메모리에 모든 애그리거트를 보관하고 있다면 아래와 같이 사용할 수 있다.

public class MemoryOrderRepository implements OrderRepository {
  public List<Order> findAll(Specification spec) {
    List<Order> allOrders = findAll();
    return allOrders.stream().filter(order -> spec.isSatisfiedBy(order)).collect(toList());
}
  • 스펙의 장점은 조합에 있다. 두 스펙을 AND 연산자나 OR 연산자로 조합해서 새로운 스펙을 만들 수 있고, 조합해서 더 복잡한 스펙을 만들 수 있다.

2. JPA를 위한 스펙 구현

위 방식에는 전체 데이터를 메모리에 로딩한 다음에 검사를 하기 때문에 성능문제가 발생한다.
Criteria-Builder나 Predicate를 사용해서 검색조건을 구현함으로써 성능문제를 해결할 수 있다.

3. 정렬 구현

  • CreteriaQuery를 설명해서 굳이 메모하지 않겠음.

4. 페이징과 개수 구하기 구현

  • CreteriaQuery를 설명해서 굳이 메모하지 않겠음.

5. 조회 전용 기능 구현

리포지터리는 애그리거트의 저장소를 표현하는 것으로서 다음 용도로 리포지터리를 사용하는 것은 적합하지 않다.

  • 여러 애그리거트를 조합해서 한 화면에 보여주는 데이터 제공
  • 각종 통계 데이터 제공
  • 동적 쿼리를 이용해서 처리해야 된다.
profile
안녕하세요

0개의 댓글