주문 조회 V6: JPA에서 DTO 직접 조회, 플랫 데이터 최적화

Order와 OrderItem, Item을 join해서 한번에 다 가져오도록 해본다! SQL에서는 flat하게 한줄로 나오기 때문에 이에 맞춰야한다.

OrderQueryDto로 바꾸고 싶다면 직접 중복을 제거해야한다.(a.k.a 노가다)

@GetMapping("/api/v6/orders")
public List<OrderFlatDto> ordersV6(){
    return orderQueryRepository.findAllByDto_flat();
}

작전 : 한번에 다 join해서 쿼리가 한번만 실행되게 한다. =>당연히 중복 결과가 나온다! API Specification은 이전과 동일하게 해서 중복되는 데이터들은 직접 복잡한 쿼리들을 작성해서 제거한다.

그러면 한번의 쿼리로 원하는 데이터를 조회할 수 있다!

@GetMapping("/api/v6/orders")
  public List<OrderQueryDto> ordersV6() {
      List<OrderFlatDto> flats = orderQueryRepository.findAllByDto_flat();
      return flats.stream()
              .collect(groupingBy(o -> new OrderQueryDto(o.getOrderId(),
  o.getName(), o.getOrderDate(), o.getOrderStatus(), o.getAddress()),
                      mapping(o -> new OrderItemQueryDto(o.getOrderId(),
  o.getItemName(), o.getOrderPrice(), o.getCount()), toList())
              )).entrySet().stream()
              .map(e -> new OrderQueryDto(e.getKey().getOrderId(),
  e.getKey().getName(), e.getKey().getOrderDate(), e.getKey().getOrderStatus(),
  e.getKey().getAddress(), e.getValue()))
              .collect(toList());
}

OrderFlatDto OrderDTO와 OrderItemDTO를 합친다!

OrderQueryRepository : 쿼리 작성

장점 : 쿼리 한번

단점

  • 쿼리는 한번이지만 조인으로 인해 DB에서 애플리케이션에 전달하는 데이터에 중복 데이터가 추가되므로 상황에 따라 V5 보다 더 느릴 수 도 있음!

  • 애플리케이션에서 추가 작업이 크다.

  • 페이징 불가능 OrderFlatDto 나 OrderItems 관련 : 페이징 가능할 수도 있지만 Order에 대해서는 페이징 불가능. =>DB에서는 여전히 중복된 데이터가 포함된 테이블이 있기 때문. ex) DB : 4, 4, 11, 11 주문번호에 따라 이렇게 저장되있는데 우리가 원하는 것은 4,11 이다. 그래서 페이징으로 (0,2) 을 하면 4,4가 나와버린다.

Last updated

Was this helpful?