[스프링 활용2] 간단한 주문 조회 V4 : JPA에서 DTO로 바로 조회

atdawn·2024년 8월 17일

SPRING BOOT+JPA

목록 보기
41/49

참고 : [실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화] - 김영한


V2, V2의 경우 엔티티를 조회해서 DTO로 중간에 변환하는 방식이었다.
이번에는 JPA에서 DTO로 바로 끄집어내어 조회하는 방법을 알아보자.

이전 버전의 SimpleOrderDto의 경우 Controller에 있었다.
이번 버전에서 repository의 메서드를 생성할때 이 DTO가 필요한데, 의존관계가 리파지토리->컨트롤러 로 생길 수 있기 때문에 repository 패키지에 DTO클래스를 따로 생성하였다.

  • 의존관계는 가급적으로 Controller -> Service -> Repository 처럼 한 방향으로만 흘러야 한다.

OrderSimpleQueryDto 생성

repository/SimpleOrderQueryDto.java

@Data
public class OrderSimpleQueryDto {

    private Long orderId;
    private String name;
    private LocalDateTime orderDate;
    private OrderStatus orderStatus;
    private Address address;

    public OrderSimpleQueryDto(Long orderId,String name,LocalDateTime orderDate,OrderStatus orderStatus,Address address) {
        this.orderId = orderId;
        this.name = name;
        this.orderDate = orderDate;
        this.orderStatus = orderStatus;
        this.address = address;
    }
}

OrderSimpleApiController

@GetMapping("api/v4/simple-orders")
public List<OrderSimpleQueryDto> ordersV4(){
    return orderRepository.findOrderDtos();
}
  • OrderRepository의 findOrderDtos() 메서드를 호출하여, DTO로 직접 조회된 결과를 반환
  • 클라이언트에 필요한 데이터를 최소한의 쿼리로 효율적으로 전달

findOrderDtos 메서드 생성

OrderRepository

public List<OrderSimpleQueryDto> findOrderDtos() {
    return em.createQuery(
            "select new jpabook.jpashop.repository.OrderSimpleQueryDto(o.id, m.name, o.orderDate, o.status, d.address)" +
                    " from Order o" +
                    " join o.member m" +
                    " join o.delivery d", OrderSimpleQueryDto.class)
            .getResultList();
}
  • 일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
  • JPQL에서 new 키워드를 사용하여 DTO를 직접 생성
  • Order 엔티티에서 id, orderDate, status를, 연관된 Member 엔티티에서 name을, Delivery 엔티티에서 address를 조회하여 OrderSimpleQueryDto의 필드에 직접 할당
  • SELECT 절에서 원하는 데이터를 직접 선택하므로 DB 애플리케이션 네트웍 용량 최적화(생각보다 미비)
  • Order 엔티티를 Member 및 Delivery 엔티티와 조인
  • 리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점

장점

  • 성능 최적화: 불필요한 엔티티를 로딩하지 않기 때문에 성능이 매우 향상. 특히, N+1 문제를 방지.
  • 쿼리 최적화: JPA 쿼리에서 직접 DTO를 생성하므로, 쿼리 최적화가 이루어집니다. 필요하지 않은 데이터를 조회하지 X.
  • 응답 데이터 최적화: API 응답에 필요한 필드만 포함된 DTO를 반환하므로, 데이터 전송량이 감소.

엔티티를 DTO로 변환하거나, DTO로 바로 조회하는 두가지 방법은 각각 장단점이 있다. 둘중 상황에 따라서 더 나은 방법을 선택하면 된다. 엔티티로 조회하면 리포지토리 재사용성도 좋고, 개발도 단순해진다. 따라서 권장하는 방법은 다 음과 같다.

쿼리 방식 선택 권장 순서
1. 우선 엔티티를 DTO로 변환하는 방법을 선택한다.
2. 필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다.
3. 그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
4. 최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.

  • 유지보수성을 향상 시키기 위해서 , 복잡한 쿼리를 가지고 있고 Repository에 있으면 용도가 애매해 지는 것들은 따로 하위 패키지를 만들어 분리하는 것이 좋다.
profile
복습 복습 복습

0개의 댓글