*인프런 '실전! 스프링부트와 JPA 활용2' 강의 내용에서 배운 내용을 정리한 것입니다*
이전 내용과 같은 방식으로 엔티티를 직접 노출하지 않고 DTO로 반환하고, 지연로딩을 사용하며, 1+N문제를 해결하기 위해 페치조인을 사용해서 컬렉션을 조회한다
/OrderApiController
@GetMapping("/api/v3/orders")
public List<OrderDto> ordersV3() {
List<Order> orders = orderRepository.findAllWithItem();
List<OrderDto> result = orders.stream()
.map(o -> new OrderDto(o))
.collect(toList());
return result;
}
/OrderRepository
public List<Order> findAllWithItem() {
return em.createQuery(
"select distinct o from Order o" +
" join fetch o.member m" +
" join fetch o.delivery d" +
" join fetch o.orderItems oi" +
" join fetch oi.item i", Order.class)
.getResultList();
}
컬렉션을 조회하는 경우는 일대다(@OneToMany),다대다(ManyToMany)이므로 조회하게되면 데이터베이스 row가 증가한다. 하나의 order에 여러개의 orderItems가 있는 경우, orderItems에 맞춰서 여러개의 order row가 생길 수 있다.
이때, distinct를 사용하면 중복을 걸러서 조회할 수 있다
-JPQL에서 distinct 기능 2가지
1. 디비에 distinct 키워드 날려주고
2. 엔티티가 중복인 경우에 중복을 걸러서 컬렉션에 담아준다
하지만 distinct를 사용하면 페이징이 불가능하다
참고: 컬렉션 페치 조인을 사용하면 페이징이 불가능하다.
두개 이상의 컬렉션에 페치 조인을 사용하면 데이터가 부정합하게 조회될 수 있어 안된다
(OrderItem과 Item은 다대일 관계이므로, orderitem을 조회할 때 Item도 같이 조회 된다)
'JPA > JPA + SpringBoot' 카테고리의 다른 글
[JPA+SpringBoot] 컬렉션 조회 최적화(DTO,지연로딩,페치조인 사용했을 때)-문제해결 (0) | 2022.03.18 |
---|---|
[JPA+SpringBoot] API 성능 최적화 (엔티티->DTO, JPA에서 바로 DTO 조회) (0) | 2022.03.18 |
[JPA+SpringBoot] 엔티티를 API에 노출했을 때 발생할 수 있는 문제점과 해결방법 (0) | 2022.03.18 |
[JPA+SpringBoot] 3/2 공부 내용 기록(웹 구현, OrderController) (0) | 2022.03.07 |
[JPA +SpringBoot] 변경감지와 병합(dirty checking, merge) (0) | 2022.03.07 |