- 경로 표현식
- 다형성 쿼리
- 엔티티 직접 사용
- Named 쿼리
- 벌크 연산
1. 경로 표현식
1. 경로 표현식 용어 정리
- 상태 필드(state field) : 단순히 값을 저장하기 위한 필드
- 연관 필드(association field) : 연관관계를 위한 필드
2. 경로 표현식 특징
- 상태 필드 : 경로 탐색의 끝. 탐색X
- 단일 값 연관 경로 : 묵시적 내부 조인(inner join) 발생. 탐색O
- 컬렉션 값 연관 경로 : 묵시적 내부 조인 발생. 탐색X(컬렉션으로 들어오는거라서 탐색을 할 수가 없음)
3. 명시적 조인 & 묵시적 조인
- 명시적 조인 : join 키워드 직접 사용
- 묵시적 조인 : 경로 표현식에 의해 묵시적으로 SQL 조인 발생(내부 조인만 가능)
4. 실무 조언
- 가급적 묵시적 조인 대신에 명시적 조인 사용
- 조인은 SQL 튜닝에 중요 포인트
- 묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어려움
5. JPQL - 페치조인(fetch join)(실무에서 정말정말 중요함)
- SQL 조인 종류X
- JPQL에서 성능 최적화를 위해 제공하는 기능
- 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
- join fetch 명령어 사용
- 즉시로딩과 비슷(만약 그냥 따로 가져온다고 하면 지연로딩 때문에 n번 SQL이 나감 → N+1 문제 발생)
- 일대다 상황
- 일에 해당하는 다의 수 만큼 컬렉션 개수가 결정됨(일대다에서 데이터가 뻥튀기 될 수 있다는 것을 유념)
- 페치 조인과 일반 조인의 차이
- 일반 조인 : 단지 SELECT 절에서 지정한 엔티티만 조회할 뿐. 연관관계 고려X
- 페치 조인 : 연관된 엔티티도 함께 조회(즉시로딩). 객체 그래프를 SQL 한번에 조회하는 개념
- 페치 조인의 특징과 한계
- 페치 조인 대상에는 별칭을 줄 수 없다.
- 둘 이상의 컬렉션은 페치 조인 할 수 없다.('일대다대다'가 되어서 곱하기가 됨 → 데이터가 예상하지 못하게 많이 늘어날 수 있음)
- 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.(데이터가 뻥튀기 되고, 페이지 사이즈 설정에 따라 정보가 누락될 수 있기 때문)
→ 해결책1. 다대일로 방향을 뒤집어서 해결
→ 해결책2. fetch join을 빼고,지연로딩으로 하는거 (근데 이거는 성능 안 나옴)
→ 해결책3. @BatchSize(size = 100)를 이용하기 = 지연로딩으로 끌어올때, 100개씩 넘기는거 (N+1을 해결하는 방법중 하나)(hibernate.default_batch_fetch_size의 value를 100으로 지정하고 진행할 수도 있음)
2. 다형성 쿼리
조회 대상을 특정 자식으로 한정
3. 엔티티 직접 사용
JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용
4. Named 쿼리
1. Named 쿼리 - 정적 쿼리
- 미리 정의해서 이름을 부여해두고 사용하는 SQL
- 어노테이션, XML에 정의
- 애플리케이션 로딩 시점에 초기화 후 재사용
- 애플리케이션 로딩 시점에 쿼리를 검증
2. Named 쿼리 - 어노테이션
3. Named 쿼리 - XML에 정의
4. SpringDateJPA 이용
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddresss);
}
- 여기에 있는 쿼리가 네임드 쿼리 역할 → 이름없는 네임드 쿼리
- JPA가 네임드쿼리로 등록해버림 → 파싱 시점에 에러 다 잡아줌
- 엔티티에 적는거는 너무 지저분해져서 springDataJpa에 섞어서 사용하기
5. 벌크 연산
- JPA는 벌크성보다는 실시간 단건에 집중되어있는 경향이 있음
→ 그래서 벌크연산이라는 것을 제공
- 벌크연산 주의 사항
(1) 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 날림
(2) 그래서, 벌크 연산을 먼저 수행 후 영속성 컨텍스트 초기화하기!!!(em.clear())
이 글은 김영한님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편'을 수강하고 정리한 내용입니다.