728x90
반응형
전 게시글과 동일한 조건에서 지연로딩으로 발생하는 1 + N 문제를 최적화하는 방법이다.
< 주어진 조건 >
- 회원 조회가 아닌 주문 조회
- REST API : GET Method 적용
- 주문과 xToOne관계로 맺어져 있는 정보를 조회할 것
- 즉, 컬렉션 조회가 아님
- 주문과 연관되어있는 회원, 배송정보를 조회할 것
- 지금까지 게시글로 원하는 API 반환을 위해서는 API 스펙에 맞춰 DTO 클래스를 설계하여 반환해야한다는 것을 알고 있다는 가정 하, DTO로 변환하여 반환하는 코드로 작성
- 조건 : API 반환으로 원하는 조건은 { 주문 번호, 사용자 이름, 주문 날짜, 주문 상태, 배송지 정보} 이다. 이 스펙에 맞춰 DTO를 개발해야한다.
@RestController
@RequiredArgsConstructor
/**
* Order
* Order -> Member
* Order -> Delivery
* 즉, 컬렉션 조회가 아닌 xToOne(ManyToOne, OneToOne) 관계
*/
public class OrderSimpleApiController {
private final OrderRepository orderRepository;
@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> ordersV3(){
List<Order> result = orderRepository.findAllWithMemberDelivery();
return result.stream()
.map(o -> new SimpleOrderDto(o))
.collect(Collectors.toList());
}
@Data
static class SimpleOrderDto{
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().getUsername();
orderDate = order.getOrderDate();
orderStatus = order.getOrderStatus();
address = order.getDelivery().getAddress();
}
}
}
@Repository
@RequiredArgsConstructor
public class OrderRepository {
private final EntityManager em;
public List<Order> findAllWithMemberDelivery(){
/**
* LAZY 설정이지만 프록시 객체가 아닌 진짜 객체로 모두 조인한 후 가져온다 -> 패치 조인
*/
return em.createQuery(
"select o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d", Order.class).getResultList();
}
}
전과 달리 변한 것은 쿼리문에 패치 조인이 적용되었다는 것 뿐이다. 만약 패치 조인을 하지 않을 경우에는
1. Order를 전부 가져온다.
2. 원하는 정보 중 Order 테이블과 연관관계가 있는 회원 Member 테이블과 Delivery 테이블을 모두 가져온 후 원하는 정보를 추출한다.
즉, 원하는 정보가 있는 테이블을 모두 가져와야했다.
하지만 패치 조인을 적용하게 되면 우리가 원하는 정보만을 하나의 테이블로 합쳐 이를 반환받는다. 따라서, 1 + N개의 쿼리문이 아닌 1개의 쿼리문으로 끝나버린다. 엄청난 최적화가 이루어질 수 있다.
실무에서 발생하는 대부분의 문제는 1 + N문제라고 한다. 패치 조인을 정확하고 올바르게 이해해야 하는 이유이다.
728x90
반응형
'Spring > API' 카테고리의 다른 글
API 개발 - 컬렉션 조회 (페치 조인 최적화) (0) | 2022.07.01 |
---|---|
API 개발 : 컬렉션 조회 (0) | 2022.06.28 |
API 개발 : 간단한 주문 조회 (지연 로딩) (0) | 2022.06.26 |
회원 조회 API 개발 / Result 클래스로 유연한 JSON 반환 (0) | 2022.06.25 |
회원 수정 API 개발 (0) | 2022.06.25 |