Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

지연 로딩과 조회 성능 최적화(JPA에서 DTO 바로 조회) 본문

인프런/[인프런] Springboot와 JPA활용 2

지연 로딩과 조회 성능 최적화(JPA에서 DTO 바로 조회)

Seung__ 2021. 8. 23. 00:20

1. Controller


 @GetMapping("/api/v4/simple-orders")
    public List<OrderSimpleQueryDto> ordersV4(){

        return orderRepository.findOrderDtos();
    }

 

 

2. Repository


  • JPA에서 DTO를 바로 조히하는 방법
    • new 명령어를 사용해서 JPQL결과를 DTO로 즉시 변환.
  • Query안에 DTO를 생성하여 값을 직접 넣어줌.
    public List<OrderSimpleQueryDto> findOrderDtos() {
        return em.createQuery(
                "select new springjpa2.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();
    }

 

 

 

3. DTO


@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;
    }
}

 

 

 

4. 쿼리 비교


  • V3 : FETCH JOIN
    • SELECT쿼리에 뭐가 많음..
    • 대신 내가 원하는 값만 가져옴.
    • 외부로 보낸 타입을 변경하지 않음.
    • FETCH JOIN의 결과는 여러 API에서 사용 가능. -> 원하는 DTO로 변경
Hibernate: 
    select
        order0_.order_id as order_id1_6_0_,
        member1_.member_id as member_i1_4_1_,
        delivery2_.delivery_id as delivery1_2_2_,
        order0_.delivery_id as delivery4_6_0_,
        order0_.member_id as member_i5_6_0_,
        order0_.order_date as order_da2_6_0_,
        order0_.status as status3_6_0_,
        member1_.city as city2_4_1_,
        member1_.street as street3_4_1_,
        member1_.zipcode as zipcode4_4_1_,
        member1_.name as name5_4_1_,
        delivery2_.city as city2_2_2_,
        delivery2_.street as street3_2_2_,
        delivery2_.zipcode as zipcode4_2_2_,
        delivery2_.status as status5_2_2_ 
    from
        orders order0_ 
    inner join
        member member1_ 
            on order0_.member_id=member1_.member_id 
    inner join
        delivery delivery2_ 
            on order0_.delivery_id=delivery2_.delivery_id
  • V4 : DTO 직접 조회
    • SELECT쿼리로 선택하는 데이터가 훨씬 적음.
    • 원하는 값을 선택에서 조회 가능.
    • 해당 DTO를 사용할 때만 사용 가능한 쿼리임.
    • 해당 REPOSITORY 재사용성이 적음.
      • 결국 API SPEC으로 REPOSITORY를 만든 것.
      • API 변경되면 REPOSITORY가 변경되어야함.. ㅜ
    • 단 성능최적화 부분에서는 V3보다는 좋음...ㅎ
    • DTO로 조회했기 때문에 엔티티 변경 불가능.
Hibernate: 
    select
        order0_.order_id as col_0_0_,
        member1_.name as col_1_0_,
        order0_.order_date as col_2_0_,
        order0_.status as col_3_0_,
        delivery2_.city as col_4_0_,
        delivery2_.street as col_4_1_,
        delivery2_.zipcode as col_4_2_ 
    from
        orders order0_ 
    inner join
        member member1_ 
            on order0_.member_id=member1_.member_id 
    inner join
        delivery delivery2_ 
            on order0_.delivery_id=delivery2_.delivery_id

 

 

 

5. V3, V4 성능차이 클까???


  • 대부분의 성능 차이는
  • join, where 조건 등에서 차이가 주된 요인이지 필드 추가는 큰 영향 없다. 

 

 

 

6. Repository는 최대한 entity를 조회하기 위해서 사용해야 한다.


  • 현재 v4는 API 스펙이 repository에 반영되어 엔티티가 아닌 dto를 조회한다..
  • 보완이 필요.
  • repository 패키지 하위에 query용 package를 추가
  • 기존  dto 조회관련 class 이동 ㅋㅋㅋ

 

 

7. 정리


엔티티를 DTO로 변환하거나 DTO로 바로 조회하는 두 가지 방법은 장단점 있음.

엔티티로 조회하면 Repository  재사용성이 좋고, 개발도 단순함

 

  • 쿼리 방식 선택 권장 순서
    • 우선 엔티티를 DTO로 변환하는 방법을 선택
    • 필요하면 FETCH JOIN으로 성능 최정화
    • 그래도 안된다면 DTO 직접 조회
    • 최후의 방법은 JPA가 제공하는 Native SQL, JDBC Template 사용하여 SQL직접 사용

 

 

8. GitHub :  210822 JPA에서 DTO 조회


 

GitHub - bsh6463/SpringBootJPA1

Contribute to bsh6463/SpringBootJPA1 development by creating an account on GitHub.

github.com

 

Comments