JPQL 경로 표현식 정리
JPQL(Java Persistence Query Language)은 객체 지향 쿼리 언어로, 엔티티 객체를 대상으로 쿼리를 작성할 수 있게 해줍니다. JPQL에서는 경로 표현식(Path Expression)을 사용하여 객체 그래프를 탐색할 수 있습니다. 이를 통해 엔티티 간의 연관 관계를 쉽게 조회할 수 있습니다. 경로 표현식에는 세 가지 종류가 있습니다:
1. 상태 필드 (State Field)
상태 필드는 단순히 값을 저장하기 위한 필드입니다. 예를 들어, m.username은 Member 엔티티의 username 필드에 접근하는 경로 표현식입니다. 상태 필드에서는 더 이상의 경로 탐색이 불가능합니다.
2. 단일 값 연관 필드 (Single-valued Association Field)
단일 값 연관 필드는 다른 엔티티를 참조하는 필드입니다. 예를 들어, m.team은 Member 엔티티와 연관된 Team 엔티티를 참조합니다. 이 경우 묵시적 내부 조인이 발생하며, 추가적인 탐색이 가능합니다. 그러나 묵시적 내부 조인은 예기치 않은 결과를 초래할 수 있으므로 주의가 필요합니다.
3. 컬렉션 값 연관 필드 (Collection-valued Association Field)
컬렉션 값 연관 필드는 다른 엔티티의 컬렉션을 참조합니다. 예를 들어, t.members는 Team 엔티티와 연관된 Member 엔티티의 컬렉션을 참조합니다. 이 경우에도 묵시적 내부 조인이 발생합니다.
묵시적 조인 피하기
묵시적 조인은 예상치 못한 결과를 초래할 수 있으므로, 명시적 조인을 사용하여 쿼리를 작성하는 것이 좋습니다. 명시적 조인은 쿼리의 의도를 명확하게 표현할 수 있습니다.
페치 조인 (Fetch Join)
페치 조인은 JPQL에서 성능 최적화를 위해 제공하는 기능으로, 데이터베이스에는 존재하지 않는 개념입니다. 주로 N+1 문제를 해결하기 위해 사용됩니다.
N+1 문제
일반적으로 아래와 같은 쿼리를 실행하면 연관된 엔티티는 프록시 객체로 조회됩니다.
프록시 객체의 실제 데이터는 나중에 접근할 때 추가적인 쿼리가 발생합니다. 이로 인해 N+1 문제가 발생합니다.
페치 조인을 사용한 N+1 문제 해결
페치 조인을 사용하면 연관된 엔티티를 한 번의 쿼리로 함께 조회할 수 있습니다. 이는 즉시 로딩과 유사하게 작동합니다.
대부분의 N+1 문제는 페치 조인을 통해 해결할 수 있습니다.
OSIV와 성능 최적화
OSIV(Open Session In View) 또는 OEIV(Open EntityManager In View)는 영속성 컨텍스트의 생존 범위를 제어하는 설정입니다.
기본 설정 (OSIV 활성화)
spring.jpa.open-in-view의 기본값은 true입니다. 이는 영속성 컨텍스트가 API의 시작부터 끝까지 유지됨을 의미하며, 이로 인해 지연 로딩이 가능합니다. 그러나 실시간 트래픽이 중요한 환경에서는 커넥션이 부족할 수 있습니다.
OSIV 비활성화
OSIV를 비활성화하면 모든 지연 로딩을 트랜잭션 내에서 처리해야 합니다. 따라서 많은 지연 로딩 코드를 트랜잭션 내로 이동시켜야 하며, View Template에서 지연 로딩이 작동하지 않습니다.
OSIV 비활성화의 장점
고객 서비스와 같이 실시간 API에서는 OSIV를 비활성화하여 커넥션 리소스를 최적화할 수 있습니다. 반면, ADMIN과 같이 커넥션을 많이 사용하지 않는 곳에서는 OSIV를 활성화할 수 있습니다.
요약
- 상태 필드: 단순 값 저장, 경로 탐색 불가능
- 단일 값 연관 필드: 묵시적 내부 조인 발생, 추가 탐색 가능
- 컬렉션 값 연관 필드: 묵시적 내부 조인 발생
- 묵시적 조인 피하기: 명시적 조인을 사용
- 페치 조인: N+1 문제 해결을 위한 성능 최적화
- OSIV: 영속성 컨텍스트 생존 범위 제어, 실시간 트래픽 환경에서의 최적화
이러한 JPQL 경로 표현식과 성능 최적화 기법을 통해 효율적인 데이터 조회와 애플리케이션 성능을 향상시킬 수 있습니다.
'JAVA > JPA' 카테고리의 다른 글
인프런 JPA 9화 값 타입 "김영한 강사" -PlusUltraCode- (1) | 2024.07.24 |
---|---|
인프런 JPA 8화 프록시와 연관관계 관리 "김영한 강사" -PlusUltraCode- (0) | 2024.07.23 |
인프런 JPA 10화 객체지향 쿼리 언어1 - 기본 문법 "김영한 강사" -PlusUltraCode- (1) | 2024.07.20 |
인프런 JPA 7화 고급 매핑 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |
인프런 JPA 6화 다양한 연관관계 매핑 "김영한 강사" -PlusUltraCode- (0) | 2024.07.20 |