주문 조회 V2: 엔티티를 DTO로 변환
Last updated
Last updated
no properties이슈 트러블 슈팅 원인 : getter/setter 가 없음 해결방법 : DTO 클래스에 @Data 또는 @Getter를 추가한다. DTO라면 @Data로 해도 된다 하지만 실무에서는 @Data가 워낙 많아서 애매한 경우는 안 쓰는 게 나을 수도 있다.
DTO(OrderDto) 생성
DTO 생성
필요한 데이터 정의
생성자 생성
orderItems는 "엔티티"이기 때문에 null이 나왔다. V1에서처럼 stream으로 반복문 돌려서 출력할 수도 있지만 좋은 방법이 아니다. stream으로 돌려서 주문 상품의 상품명을 출력하는 코드 : 주문 상품 컬렉션에서 각 객체의 이름 조회
프록시 객체 강제 초기화 : public OrderDto에서 order.getOrderItem().stream().forEach(o -> o.getItem().getName())
우리가 만든 DTO(OrderrDto) 안에는 엔티티가 있는데, DTO 안에는 엔티티가 있으면 안 된다! 엔티티가 외부에 노출되기 때문이다! 엔티티는 외부에 노출되면 안 되는데 이것을 DTO로 만든다고 해도 엔티티는 그대로 노출된다. 엔티티 의존성을 모두 없애야 한다! =>단순히 DTO로 만드는 것이 아니라, DTO 내부에서 엔티티가 있으면 안 된다!!! (Address 같은 Value Object는 가능)
그래서 List<OrderItem> 도 모두 DTO로 바꿔야 한다! 그렇지 않으면 추후에 OrderItem 엔티티 수정하게 된다면 API도 다 바뀐다!! =>statlc class OrderItemDto {...} 생성 필요!
OrderDto의 내부에 OrderItem도 마찬가지로 DTO 생성, 필요한 데이터 정의, 생성자 생성 (참고 : 여전히 배열 타입으로 반환하고 있지만 배열 타입으로 반환❌)
코드 정리 1. OrderRepository에서 List<Order> 엔티티 조회 : 실무에서는 페이징. 2. 반복문 돌리면서 OrderDto로 변환. 3. OrderDto 내에서도 List<OrderItem> 또한 DTO로 생성해서 DTO로 반환한다! => OrderItemDTO 생성해서 원하는 데이터들 정의하고 리턴
SQL문 분석 SQL은 얼마나 실행될까?
N+1문제
Order 엔티티(List<Order>) 조회 : 2건 조회
각 Order 객체는 반복문 돈다. 1. Member 조회 2. Delivery 조회 3. List<OrderItem> 조회 : 각 회원별로 주문한 상품 갯수만큼 반복. 여기서는 2개 orderItem 조회
=>한번의 주문 조회로 5*2 + 1 = 11개의 쿼리가 발생하는 것을 알 수 있다.
N+1문제 Order 조회 시, 2건의 Order 존재.
첫번째 Order부터 반복문 돈다. - Member, Address, List<OrderItem> 가져온다. List<OrderItem> 모두 지연 로딩.
=>컬렉션으로 일대다 관계에서 테이블을 조회하면 N+1 문제 발생!