*인프런 '실전! 스프링부트와 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도 같이 조회 된다)

 

 

+ Recent posts