네이버 클라우드 캠프

JPA_엔티티 그래프

99duuk 2024. 5. 28. 17:36

엔티티 그래프를 비유적으로 설명하겠습니다.

비유: 쇼핑 카트와 고객 정보

상황: 당신은 온라인 쇼핑몰에서 쇼핑 카트와 고객 정보를 처리하는 시스템을 개발 중입니다. 쇼핑 카트에는 여러 개의 상품이 담길 수 있고, 고객 정보에는 고객의 개인 정보와 주문 내역이 포함됩니다.

일반적인 로딩 (N+1 문제)

  • 상황: 쇼핑 카트에 10개의 상품이 담겨 있고, 이를 데이터베이스에서 로드하려고 합니다.
  • 일반적인 방식:
    • 먼저 쇼핑 카트 정보를 가져옵니다 (1번의 쿼리).
    • 그 후, 각 상품 정보를 개별적으로 가져옵니다 (10번의 쿼리).
  • 결과: 총 11번의 쿼리가 실행됩니다. 이를 N+1 문제라고 합니다.

엔티티 그래프 (해결책)

  • 상황: 같은 쇼핑 카트 정보를 로드하려고 합니다.
  • 엔티티 그래프 사용:
    • 쇼핑 카트와 연관된 모든 상품 정보를 한 번에 가져오는 쿼리를 실행합니다.
  • 결과: 단 1번의 쿼리로 쇼핑 카트와 모든 상품 정보를 가져올 수 있습니다.

비유 설명

  1. 비유 대상: 쇼핑 카트와 고객 정보.
    • 쇼핑 카트: 메인 엔티티 (예: Product).
    • 상품들: 연관된 엔티티들 (예: ProductImage).
  2. 일반적인 로딩:
    • 쇼핑 카트를 가져온 후, 각 상품을 개별적으로 가져옴.
    • 여러 번의 데이터베이스 쿼리가 실행됨.
  3. 엔티티 그래프 사용:
    • 쇼핑 카트와 모든 상품 정보를 한 번에 가져옴.
    • 단 1번의 데이터베이스 쿼리로 모든 관련 정보를 가져옴.

 

 

 

 

계산대 앞에 선 쇼핑카트를 예로 들면

  1. 일반적인 로딩:
    • 특정 쇼핑카트를 가져옵니다.
    • 그 쇼핑카트에 담긴 상품들을 개별적으로 하나씩 찍어서 정보를 가져옵니다.
    • 여러 번의 데이터베이스 접근(쿼리)이 필요합니다.
  2. 엔티티 그래프 사용:
    • 특정 쇼핑카트와 그 카트에 담긴 모든 상품을 한 번에 목록에 작성해둡니다.
    • 한 번에 찍어서 모든 정보를 가져옵니다.
    • 단 한 번의 데이터베이스 접근(쿼리)으로 필요한 모든 정보를 가져옵니다.

이 비유는 엔티티 그래프를 사용하여 연관된 엔티티를 효율적으로 로드하고, 여러 번의 데이터베이스 쿼리를 줄여 성능을 최적화하는 방법을 잘 설명해줍니다.

 

 

 

 

 


@EntityGraph 어노테이션의 attributePaths 속성은 엔티티 그래프를 통해 페치(fetch)할 연관된 엔티티의 경로를 지정합니다. 즉, 어떤 연관된 엔티티를 함께 로드할지 명시하는 것입니다.

비유 설명

비유에서 attributePaths는 "특정 쇼핑카트와 그 카트에 담긴 모든 상품"을 지정하는 역할을 합니다.

 

 

요약

  • @EntityGraph(attributePaths = "imageList"):
    • attributePaths는 엔티티 그래프를 통해 페치할 연관된 엔티티의 경로를 지정합니다.
    • 여기서는 Product 엔티티의 imageList 필드를 지정하여, Product와 연관된 ProductImage 엔티티들을 한 번에 로드합니다.
    • 이를 통해 여러 번의 데이터베이스 접근을 줄이고, 한 번의 쿼리로 필요한 모든 데이터를 가져옵니다.

이렇게 하면 엔티티 그래프를 사용하여 연관된 엔티티를 효율적으로 로드할 수 있으며, 성능 최적화에 도움이 됩니다.

 

 

 


 

to

 

 

 

 

  • 단일 Product:
    • Product를 로드하는 쿼리 1개.
    • 연관된 ProductImage를 로드하는 쿼리 1개.
  • 100개의 Product:
    • Product를 로드하는 쿼리 1개.
    • 각 Product에 대해 ProductImage를 로드하는 쿼리 100개.
    • 총 101개의 쿼리 실행.

 


엔티티 그래프(Entity Graph)와 페치 조인(Fetch Join)은
 
JPA에서 연관된 엔티티를 효율적으로 로드하기 위한 두 가지 방법입니다.
 

이 두 가지 방법은 비슷한 목적을 가지고 있지만, 사용 방식과 장단점에서 차이가 있습니다.

 

 

엔티티 그래프 (Entity Graph)

  • 목적: 엔티티를 로드할 때 특정 연관된 엔티티도 함께 로드하도록 명시합니다.
  • 사용 방법: 주로 @EntityGraph 어노테이션을 사용하여 지정합니다.
  • 적용 위치: 리포지토리 메서드에 적용하여 특정 쿼리에 대해 엔티티 그래프를 사용합니다.

예시

  • 설명: findByPno 메서드는 Product 엔티티를 로드할 때 연관된 ProductImage 엔티티도 함께 로드합니다.

 

 

페치 조인 (Fetch Join)

  • 목적: JPQL 쿼리에서 명시적으로 연관된 엔티티를 한 번의 쿼리로 함께 로드합니다.
  • 사용 방법: JPQL 쿼리에서 JOIN FETCH 구문을 사용합니다.
  • 적용 위치: JPQL 쿼리문 내에서 직접 사용합니다.

예시

 

  • 설명: findByPnoWithImages 메서드는 JPQL 쿼리에서 JOIN FETCH를 사용하여 Product와 연관된 ProductImage 엔티티를 함께 로드합니다.

 

비교

특성엔티티 그래프 (Entity Graph)페치 조인 (Fetch Join)
 
사용 위치 리포지토리 메서드 JPQL 쿼리
구문 @EntityGraph(attributePaths = "...") JOIN FETCH
적용 범위 메서드 레벨 쿼리 레벨
유연성 연관된 엔티티를 동적으로 로드 가능 명시적인 쿼리 작성 필요
장점 코드가 더 간결하고 재사용성이 높음 복잡한 쿼리를 작성할 수 있음
단점 복잡한 쿼리 작성에는 한계가 있음 코드가 길어질 수 있고 재사용성 낮음

 

 

관계 요약

  • 엔티티 그래프는 더 간결하고 메서드 레벨에서 쉽게 사용할 수 있어 코드의 재사용성을 높입니다.
  • 페치 조인은 복잡한 쿼리를 작성할 때 유용하며, 더 구체적이고 세밀한 제어가 가능합니다.
  • 둘 다 연관된 엔티티를 효율적으로 로드하기 위한 방법이지만, 사용 용도와 상황에 따라 선택할 수 있습니다.

이 두 방법을 적절히 사용하면 N+1 문제를 해결하고, 데이터베이스 접근을 최적화할 수 있습니다.

'네이버 클라우드 캠프' 카테고리의 다른 글

@ElementCollection_임베디드 테이블  (0) 2024.05.31
CORS, CSRF  (0) 2024.05.31
JPA_값 타입 객체  (0) 2024.05.28
React 입문 -  (0) 2024.05.19
React 입문 - Hook, props  (0) 2024.05.18