JPA #6 - 지연로딩과 조회 성능 최적화
업데이트:
JPA 학습
API 개발 고급 - 지연로딩과 조회 성능 최적화
조회용 샘플 데이터 입력
@PostConstruct:spring bean이 다 올라오고 나면spring이 호출 해 준다.
간단한 주문 조회 V1: 엔티티를 직접 노출
- 양방향 연관관계 문제 : 한 객체에
JsonIgnore로 연관관계를 끊는다. Lazy Loading하게 되면 연관관계의 대상이 되는 객체의 데이터를DB에서 가져오지 않는다. 해당 객체에null을 넣어 놓을 수 없으니,Proxy Library에서 해당 객체를 상속받아proxy 객체즉,ByteBuddyInterceptor를 넣어놓는다.- 만들어 놓은
proxy 객체를 사용 할 일이 있을 때,sql을 날려 해당 데이터를 가져온다. 이것을proxy 객체를 초기화 한다고 한다. Hibernate5Module을 사용하여Lazy Loading인 객체들을null처리하여 가져올 수 있고force lazy하여Lazy Loading인 객체들을 전부 가져올 수도 있다. 하지만 이러한 방식들은 권장되는 방법이 아니다. (쿼리낭비 등)Lazy Loading을 피하기 위해Fetch type = Eager으로 바꾸는 것은JPQL N+1문제나, 연관관계가 필요하지 않는 경우에도 데이터를 항상 조회해서 등 성능의 문제가 발생 할 수 있고 성능 튜닝이 매우 어려우므로 사용하지 않도록 한다.- 성능 최적화가 필요한 경우에는
fetch join을 사용한다.
간단한 주문 조회 V2: 엔티티를 DTO로 변환
DTO로 생성하여 응답한다.V1과V2의 문제점? 어미어마한 쿼리의 낭비가 있다. (N+1문제)FetchType=LAZY로 설정된 객체들은proxy 객체로 존재하다가, 해당 데이터 호출 시 영속성 컨텍스트를 먼저 조회한다. 그리고 없다면 DB에 쿼리를 날려 조회한다.
간단한 주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화
fetch join은 성능 최적화에 아주 많이 사용되므로 꼭 이해하도록 하자.JPQL에서join fetch를 사용하여, 연관 테이블을 한번에 가져와 성능 최적화 할 수 있다.- 장점으로는 재사용성이 높지만, 단점으로는 테이블의 불필요한 컬럼까지 다같이 조회한다.
간단한 주문 조회 V4: JPA에서 DTO로 바로 조회
- 기본적으로
JPA는 쿼리문에서Entity나VO만 반환 할 수 있다. JPQL을JdbcTemplate처럼 필요한 컬럼만 가져와서 각각 맵핑시켜서 사용 할 수 있다.- 장점으로는 정말 필요한 컬럼만 가져오지만, 단점으로는 정말 해당 DTO를 위해서 만들어진 쿼리이기 때문에 재사용성이 없다.
- 성능이 좋지만
API에 의존적이여서 논리적 계층구조가 깨져버린다.Repository는Entity를 조회하는 용도로 사용해야 하는데DTO를 조회해버린다.API조회용QueryRepository생성하여 관리하는 것도 하나의 방법이다.
댓글남기기