인프런 커뮤니티 질문&답변

rr8602님의 프로필 이미지

작성한 질문수

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

간단한 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화

결과 쿼리 개수가 맞지 않아서 문의 드립니다.

23.10.25 22:05 작성

·

510

·

수정됨

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예

[질문 내용]

[간단한 주문 조회 V3: 엔티티를 DTO로 변환 -패치 조인 최적화] 강의에서 5분 50초 쯤에 v2를 돌려봤을 때, 강사님은 쿼리가 5번 나오는데,

저는 계속 7번이 나오더라구요...

order가 처음에 주문 2개를 만들어서 이미 영속성 상태라 그 다음에는 1차 캐시에서 가져오는 것으로 보여 쿼리는 생성이 안되어야 한다고 생각이 드는데, 왜 계속 order 쿼리가 2번 더 나오는 걸까요...?

 

[Query]

2023-10-25T21:54:33.448+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

o1_0.order_id,

o1_0.deliver_id,

o1_0.member_id,

o1_0.order_date,

o1_0.status

from

orders o1_0

join

member m1_0

on m1_0.member_id=o1_0.member_id

fetch

first ? rows only

2023-10-25T21:54:33.449+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473449 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id fetch first ? rows only

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id fetch first 1000 rows only;

2023-10-25T21:54:33.450+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

m1_0.member_id,

m1_0.city,

m1_0.street,

m1_0.zipcode,

m1_0.name

from

member m1_0

where

m1_0.member_id=?

2023-10-25T21:54:33.451+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473451 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?

select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=1;

2023-10-25T21:54:33.451+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

d1_0.delivery_id,

d1_0.city,

d1_0.street,

d1_0.zipcode,

d1_0.status

from

delivery d1_0

where

d1_0.delivery_id=?

2023-10-25T21:54:33.451+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473451 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?

select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=1;

2023-10-25T21:54:33.452+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

o1_0.order_id,

o1_0.deliver_id,

o1_0.member_id,

o1_0.order_date,

o1_0.status

from

orders o1_0

where

o1_0.deliver_id=?

2023-10-25T21:54:33.452+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473452 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=?

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=1;

2023-10-25T21:54:33.453+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

m1_0.member_id,

m1_0.city,

m1_0.street,

m1_0.zipcode,

m1_0.name

from

member m1_0

where

m1_0.member_id=?

2023-10-25T21:54:33.453+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473453 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?

select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=2;

2023-10-25T21:54:33.453+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

d1_0.delivery_id,

d1_0.city,

d1_0.street,

d1_0.zipcode,

d1_0.status

from

delivery d1_0

where

d1_0.delivery_id=?

2023-10-25T21:54:33.454+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473454 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?

select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=2;

2023-10-25T21:54:33.454+09:00 DEBUG 37176 --- [nio-8080-exec-3] org.hibernate.SQL :

select

o1_0.order_id,

o1_0.deliver_id,

o1_0.member_id,

o1_0.order_date,

o1_0.status

from

orders o1_0

where

o1_0.deliver_id=?

2023-10-25T21:54:33.454+09:00 INFO 37176 --- [nio-8080-exec-3] p6spy : #1698238473454 | took 0ms | statement | connection 11| url jdbc:h2:tcp://localhost/~/jpashop2

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=?

select o1_0.order_id,o1_0.deliver_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.deliver_id=2;

 

 

 

 

[OrderSimpleApiController]

package jpabook.jpashop2.api;

import jpabook.jpashop2.Repository.OrderRepository;
import jpabook.jpashop2.Repository.OrderSearch;
import jpabook.jpashop2.domain.Address;
import jpabook.jpashop2.domain.Order;
import jpabook.jpashop2.domain.OrderStatus;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;
import ja
va.util.stream.Collectors;

/**
* X To One (컬렉션 X)
* Order
* Order -> Member
* Order -> Delivery
*/
@RestController
@RequiredArgsConstructor
public class OrderSimpleApiController {

private final OrderRepository orderRepository;

@GetMapping("/api/v1/simple-orders")
public List<Order> ordersV1(){
List<Order> all = orderRepository.findAllByString(new OrderSearch());
for (Order order : all) {
order.getMember().getName(); // Lazy 강제 초기화
order.getDelivery().getAddress(); // Lazy 강제 초기화
}
return all;
}

@GetMapping("/api/v2/simple-orders")
public List<SimpleOrderDto> ordersV2(){
// Order 2개
List<Order> orders = orderRepository.findAllByString(new OrderSearch());

List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o)) // map : a -> b로 치환
.collect(Collectors.toList());
return result;
}

@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> ordersV3() {

List<Order> orders = orderRepository.findAllWithMemberDelivery();
List<SimpleOrderDto> result = orders.stream()
.map(o -> new SimpleOrderDto(o))
.collect(Collectors.toList());

return result;
}


@Data
static class SimpleOrderDto{ // API 명세서
private Long orderId;
private String name;
private LocalDateTime orderDate;
private OrderStatus orderStatus;
private Address address;

public SimpleOrderDto(Order order) {
orderId = order.getId();
name = order.getMember().getName();
orderDate = order.getOrderDate();
orderStatus = order.getStatus();
address = order.getDelivery().getAddress();
}
}
}

 

 

[OrderRepository]

...

 

public List<Order> findAllWithMemberDelivery() {
return em.createQuery("select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class)
.getResultList();
}

 

답변 2

1

김영한님의 프로필 이미지
김영한
지식공유자

2023. 10. 27. 17:01

안녕하세요. rr8602님

다음을 참고해주세요 :)

https://www.inflearn.com/questions/1040920

감사합니다.

0

codesweaver님의 프로필 이미지

2023. 10. 26. 16:37

안녕하세요. rr8602님, 공식 서포터즈 코즈위버 입니다.

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

실제 동작하는 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx


주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요


추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명

감사합니다.

rr8602님의 프로필 이미지

작성한 질문수

질문하기