inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

주문 조회 V3.1: 엔티티를 DTO로 변환 - 페이징과 한계 돌파

v3.1 쿼리 최적화

352

하하하

작성한 질문수 12

0

안녕하세요 선생님!

v3.1에서 쿼리 실행 결과 order 조회-> orderItem 조회 -> item 이 조회됩니다.

저는 OrderItem 안에 item이 Lazy 로딩이니 페치 조인으로 가지고 오고 싶어서 다음과 같은 로직을 작성해보았습니다.  

@GetMapping("/api/v3.2/orders")
public List<OrderDto> ordersV3_page2(
@RequestParam(value = "offset", defaultValue = "0") int offset,
@RequestParam(value = "limit", defaultValue = "100") int limit
) {
List<Order> orders = orderRepository.findWithMemberDelivery(offset, limit);
List<Long> ids = orders.stream().map(order -> order.getId()).collect(toList());
List<OrderItem> orderItems = orderQueryRepository.findOrderDto(ids);
return orders.stream()
.map(order -> new OrderDto(order, orderItems))
.collect(toList());
}
public List<OrderItem> findOrderDto(List<Long> ids) {
return em.createQuery(
"select oi from OrderItem oi join fetch oi.item where oi.order.id in :ids", OrderItem.class)
.setParameter("ids", ids)
.getResultList();
}
public OrderDto(Order order, List<OrderItem> orderItems) {
orderId = order.getId();
name = order.getMember().getName();
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress();
this.orderItems = orderItems.stream().map(OrderItemDto::new).collect(toList());
}

이와 같이 로직을 작성 하고 결과를 확인하니 

 

 

위와 같이 모든 Item이 조회되었습니다.

 

혹시 fetch join 이 문제 일까 싶어서 fetch join 을 제외하고  실행하더라도 동일한 결과가 나왔습니다.

 

fetch join을 빼고 실행하면 강의에서 나온 것과 동일하게 쿼리가 실행되지만 결과값은 다른 것을 확인했습니다. -> batch_fetch_size를 사용했을때만 동일한 쿼리가 실행됨.(결과값은 다름)

batch_fetch_size 사용 시 단순히 in 쿼리로 결과를 가져오는 것이 아니라 지연로딩을 생각해서 결과값을 가져온다고 생각하면 되는걸까요? 동일한 쿼리가 실행되는데도 결과 값이 다르게 나오는게 이해가 잘안됩니다 ㅠㅠ

 

 

 

java JPA spring spring-boot

답변 1

1

김영한

안녕하세요. 김진욱님

작성하신 findOrderDto에서 모든 OrderItem들을 다 조회해버리는데요.

그것을 다음 로직에서 그대로 각각 다 넣어버리니, 각각 모든 OrderItem을 가지게 됩니다.

OrderDto를 만드는 단계에서 자신의 것만 가지도록 분류해주시던가 해야할 것 같아요.

 

public OrderDto(Order order, List<OrderItem> orderItems) {

   orderId = order.getId();

   name = order.getMember().getName();

   orderDate = order.getOrderDate();

   orderStatus = order.getStatus();

   address = order.getDelivery().getAddress();

   this.orderItems = orderItems.stream().map(OrderItemDto::new).collect(toList());

}

감사합니다.

강의 관련 외 질문입니다.

0

81

2

SpringBoot4 + Hibernate7 모듈 등록 방법 공유

1

99

1

BeanCreationException

0

96

3

Update 후 UpdateMemberResponse 매핑할 때

0

57

1

트랜잭션을 사용 안 할 때 커넥션은 언제 가져오나요?

0

102

2

페이징 + 검색조건 관련해서 질문드립니다.

0

74

1

Query Dsl Q파일 질문입니다.

0

86

1

루트 쿼리라는것은

0

62

1

메서드를 분리하는 기준

0

71

1

findAllWithMemberDelivery 메서드 질문드립니다.

0

116

3

연관관계 매핑을 안 쓸 경우, 사용해야 하는 전략

0

92

2

fetch join과 영속화와 OSIV의 관계

0

90

2

Distinct 사용 전 결과에 대한 의문

0

118

2

레포지토리 계층에서의 트랜잭션에 대한 의문

0

63

1

영속성 컨텍스트 생명주기의 신기한 부분이 있습니다.

0

79

2

dto 필드 속 엔티티 여부

0

63

1

뷰템플릿 사용 시

0

82

2

Result 클래스 관련 질문

0

56

1

@PostConstruct 프록시 관련 질문드립니다

0

88

1

DTO 대신 Form 사용은 안되나요?

0

140

1

OSIV ON 상태일 때

0

99

1

fetch join VS fetch join 페이징 궁금증

0

190

2

양방향 연관관계 알아보는 법?

0

110

1

16강 17강 간단 정리 이게 맞을까요 ?

0

168

2