Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

컬렉션 조회 최적화 : 플랫 데이터 최적화 본문

인프런/[인프런] Springboot와 JPA활용 2

컬렉션 조회 최적화 : 플랫 데이터 최적화

Seung__ 2021. 8. 25. 22:55

다 조인시켜서 한방쿼리로 가져오자.

 

1. OrderFlatDto


  • Order와  OrderItem을 join해서 DTO로 한번에 가져올 예정.
  • DB에서 join하면 한줄로 쭉 join 되듯이 데이터 구조를 맞춤.
@Data
public class OrderFlatDto {

    //order
    private Long orderId;
    private String name;
    private LocalDateTime orderDate;
    private OrderStatus orderStatus;
    private Address address;

    //orderItem
    private String itemName;
    private int orderPrice;
    private int count;


    public OrderFlatDto(Long orderId, String name, LocalDateTime orderDate, OrderStatus orderStatus, Address address, String itemName, int orderPrice, int count) {
        this.orderId = orderId;
        this.name = name;
        this.orderDate = orderDate;
        this.orderStatus = orderStatus;
        this.address = address;
        this.itemName = itemName;
        this.orderPrice = orderPrice;
        this.count = count;
    }
}

 

 

2.  DB에서 가져올때 OrderFlatDto로 가져오자.


   public List<OrderFlatDto> findAllByDto_flat() {

        return em.createQuery(
                "select new " +
                        "springjpa2.repository.order.query.OrderFlatDto(o.id, m.name, o.orderDate, o.status, d.address, i.name, oi.orderPrice, oi.count) " +
                        "from Order o " +
                        "join o.member m " +
                        "join o.delivery d " +
                        "join o.orderItems oi " +
                        "join oi.item i", OrderFlatDto.class)
                .getResultList();
    }

 

 

 

3. 실행 & 결과


 @GetMapping("/api/v6/orders")
    public List<OrderFlatDto> ordersV6(){
        return orderQueryRepository.findAllByDto_flat();
    }
  • order와  orderItem이 조인되어 DTO로 가져왔다.

 

 

 

4. 하지만 현재 반환 타입이 OrderFlatDto로

이전에 만든 v5랑 API 스펙이 다르다.


따라서 V5 API  스펙과 동일하게 맞줘야 할 필요가 있다.

 

어떻게? 내가 직접 중복을 거르면 된다.

 

그런데 o를 참조하지 못한다.. 뭐지..

  • Order와 OrderItem을 하나로 합친 flasts를 루프를 돌면서
  • Order와 OrderItem으로 분리하고 OrderId를 기준으로  mapping한다.
  • 이후 map을 통해 OrderQueryDto로 변환한다.
@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());
}
  • 위와 같이 실행하면 쿼리는 한번으로 끝이 나고
  • DB에서 애플리케이션으로 보내는 중복 데이터를 직접 제거한다.
  • 따라서 애플리케이션에서 추가 작업이 크고
  • 페이징 불가능.(order를 기준으로 페이징 불가능)

 

5. GitHub : 210825 collection, flat data


 

GitHub - bsh6463/SpringBootJPA1

Contribute to bsh6463/SpringBootJPA1 development by creating an account on GitHub.

github.com

 

Comments