Search
Duplicate

[스프링부트와 JPA 활용] API 개발 고급 - 지연 로딩과 조회 성능 최적화⭐⭐⭐⭐⭐

날짜
2022/04/26 06:55
상태
실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
속성 1
JAVA
Spring
JPA
API
담당자
목차

API 개발 고급 - 준비

InitDb
Code
실무에서 많이 실수하고 어려운 부분 꼭 익혀야된다.

간단한 주문 조회 V1: 엔티티를 직접 노출

Code
엔티티를 직접 노출하는 것은 좋지 않다.
order → member와 order→address는 지연 로딩이다. 따라서 실제 엔티티 대신에 프록시 존재
jackson 라이브러리는 기본적으로 이 프록시 객체를 json으로 어떻게 생성해야 하는지 모름 → 예외발생
Hibernate5Module을 스프링 빈으로 등록하면 해결 → 하지만 이렇게 작성하면 엔티티를 노출 할 수 밖에 없다. 대문에 DTO를 만들어서 해결해주는게 제일 좋다.
주의: 엔티티를 직접 노출할 때는 양방향 연관간계가 걸린 곳은 꼭! 한곳을 @JsonIgnore 처리를 해야한다. 안그러면 양쪽을 서로 호풀하면서 무한 루프가 걸린다.
참고: 앞에서 계속 강조했듯이 정말 간단한 애플리케이션이 아니면 엔티티를 API 응당으로 외부로 노출하는 것은 좋지 않다. 따라서 Hibernate5Moudle를 사용하기 보다는 DTO로 변환하는 것이 더 좋은 방법이다.
주의: 항상 지연 로딩을 기본으로 하고, 성능 최적화가 필요한 경우에는 페치 조인을 사용해라!

간단한 주문 조회 V2: 엔티티를 DTO로 변환

Code
엔티티를 DTO로 변환하는 일반적인 방법이다.
쿼리가 총 1 + N + N번 실행된다. (v1과 쿼리수 결과는 같다.)
order 조회 1번(order 조회 결과 수가 N이 된다.)
order → member 지연 로딩 조회 N번
order → delivery 지연 로딩 조회 N 번
예) order의 결과가 4개면 최악의 경우 1 + 4 + 4번 실행된다.
지연로딩은 영속석 컨텍스트에서 조회하므로, 이미 조회된 경우 쿼리를 생략한다.

간단한 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화

Code
엔티티를 페치 조인(fetch hoin)을 사용해서 쿼리 1번에 조회
페치 조인으로 order→member, meber→delivery는 이미 조회 된 상태 이므로 지연로딩X

간단한 주문 조회 V4: JPA에서 DTO로 바로 조회

Code : OrderSimpleApiController - 추가
Code: OrderSimpleQueryRepository 조회 전용 리포지토리
Code: OrderSimpleQueryDto 리포지토레이서 DTO 직접 조회
일반적인 SQL을 사용할 때 처럼 원하는 값을 선택해서 조회
new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 변환
SELECT 절에서 원하는 데이터를 직접 선택하므로 DB → 애플리케이션 네트웍 용량 최적화
리포지토리 재사용성 떨어짐, API 스펙에 맞춘 코드가 리포티조리에 들어가는 단점

정리

엔티티를 DTO로 변환하거나, DTO로 바로 조회하는 두가 방법은 각각 장단점이 있다. 둘중 상황에 따라서 더 나은 방법을 선택하면 된다. 엔티티로 조회하려면 리포지토리 재사용성이 좋고, 개발도 단순해진다. 따라서 권장하는 방법은 다음과 같다.
쿼리 방식 선택 권장 순서
1.
우선 엔티티를 DTO로 변환하는 방법을 선택한다.
2.
필요하면 페치 조인으로 성능을 최적화 한다. → 대부분의 성능 이슈가 해결된다.
3.
그래도 안되면 DTO로 직접 조회하는 방법을 사용한다.
4.
최후의 방법은 JPA가 제공하는 네이티브 SQL이나 스프링 JDBC Template을 사용해서 SQL을 직접 사용한다.