간단한 주문 조회 V4: JPA에서 DTO로 바로 조회(버전별 비교 분석)
V2, V3까지는 엔티티를 조회해서 DTO로 변환했다.
이제는 JPA에서 DTO로 바로 조회한다!
일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환
SELECT 절에서 원하는 데이터를 직접 선택하므로 DB 애플리케이션 네트웍 용량 최적화(생각보다 미비)
리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점
Repository에서 Controller 의존관계 생기면 안된다! 컨트롤러에서 서비스, 서비스에서 리포지토리 이렇게 가급적이면 한 방향으로 흘러야한다!
JPA는 엔티티나 임베디드 타입 같은 값 타입만 반환 가능하다. (DTO에서 생성자가 매핑해주는 것이 아니다.) DTO 반환하려면 new 연산자를 꼭 써야한다! new 연산자로 엔티티를 바로 넘기면 안 된다!왜냐하면 엔티티가 식별자로 넘어가기 때문이다!(??)
기존의 SimpleDto를 클래스로 따로 뺀다. - OrderSimpleQueryDto =>리포지토리 하위에 패키지를 두고 여기에 별도로 둔다!
내부의 생성자를 통해 엔티티를 받고 있지만, 엔티티를 받으면 안 된다!
V3, V4 차이점
V3 | V4 | |
차이점 | fetch join으로 모든 데이터를 select문으로 구성 | 원하는 데이터만 select 쿼리 직접 작성 |
Order Repository | List<Order> findAllWithMemberDelivery() | List<OrderSimpleQueryDto> findOrderDto() |
외부는 건드리지 않고 내부에서 fetch join으로 성능 튜닝=>재사용 가능 | JPQL로 원하는 데이터들 쿼리를 직접 작성했으므로 재사용❌ | |
반환 타입, 조회 타입 | 엔티티 반환&조회 | DTO 반환&조회=>수정/변경❌ 엔티티가 아니기 때문에 |
코드 작성 쉬움 | 쿼리문 직접 작성=>코드 복잡해지기 쉬움 |
리포지토리 용도 : 엔티티, 객체 그래프 조회 등에 사용 하지만 V4에서는 리포지토리가 API 스펙에 맞춰 작성되었다!
리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포지토리에 들어가는 단점 =>리포지토리에서 API에 의존하고 있다고 할 수 있다.
대부분의 경우 V3, V2 성능 차이 미비 => 요즘 네트워크 밴더들이 제공하는 네트워크 상태나 질이 좋기 때문에 빠르다.
V3, V4의 쿼리 차이는 select문에서 무엇을 얼마나 조회하느냐인데 실제 성능에 영향을 끼치는 것은 조인이나 where절이다. 애플리케이션 전체 관점에서 보면 select절은 성능에 크게 영향을 주지는 않는다. 문제는 따로 있다!
만약 select해야하는 것이 20-30개, 현재의 API가 트래픽이 엄청 많이 들어오는가?를 고민하면서 최적화.
⭐️V4 개선 : 화면에 의존적인 부분을 리포지토리와 분리 Repository 하위에 성능최적화한 쿼리용 패키지를 하나 만든다! 리포지토리는 엔티티를 검색/조회하고, 필요에 따라 fetch join으로 최적화하는것 정도만 한다!!
OrderSimpleQueryRepository리포지토리 : 조회 전용 리포지 토리(JPQL 쿼리 최적화)
OrderSimpleQueryDto 리포지토리 : DTO 직접 조회
⭐️쿼리 방식 선택 권장 순서 (웬만하면 2번에서 다 해결된다고 함.)
우선 엔티티를 DTO로 변환하는 방법을 선택한다. - V2
필요하면 페치 조인으로 성능을 최적화 한다. 대부분의 성능 이슈가 해결된다. - V3
그래도 안되면 DTO로 직접 조회하는 방법을 사용한다. - V4
최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접
Last updated