자바 ORM 표준 JPA 프로그래밍 기본편 - 10. 객체지향 쿼리 언어2 - 중급 문법
Updated:
김영한님의 인프런 강의 - 자바 ORM 표준 JPA 프로그래밍 - 기본편
위 강의를 정리한 내용입니다.
경로 표현식
- .(점)을 찍어 객체 그래프를 탐색하는 것
select m.username -> 상태필드 from Member m join m.team t -> 단일 값 연관 필드 join m.orders o -> 컬렉션 값 연관 필드 where t.name = '팀A'
- 상태 필드 : 단순히 값을 저장하기 위한 필드
- 연관 필드 : 연관관계를 위한 필드
- 단일 값 연관 필드 : @ManyToOne, @OneToOne, 대상이 엔티티
- 컬렉션 값 연관 필드 : @ManyToMany, @OneToMany, 대상이 컬렉션
특징
- 상태 필드 : 경로 탐색의 끝, 탐색X
- 단일 값 연관 경로 : 묵시적 내부 조인 발생, 탐색O
- 컬렉션 값 연관 경로 : 묵시적 내부 조인 발생, 탐색 X
- FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능
SELECT t.members FROM Team t - X
SELECT m FROM Team t join t.members m - O
- FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능
묵시적 내부 조인 방식은 쓰지 말고 꼭 명시적 조인 방식을 사용하자
페치 조인(fetch join)
SELECT m FROM Member m join fetch m.team
- JPQL에서 성능 최적화를 위해 제공하는 기능
- 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
컬렉션 페치 조인
SELECT t FROM Team t join fetch t.members where t.name = ‘팀A’
- 일대다 관계
- 중복된 결과가 나올 수 있음 :
DISTINCT
사용
SELECT distinct t FROM Team t join fetch t.members where t.name = ‘팀A’
DISTINCT
가 추가로 애플리케이션에서 중복 제거시도- 같은 식별자를 가진 엔티티를 제거
특징 및 한계
- 페치 조인 대상에는 별칭을 줄 수가 없다.
- 하이버네이트는 가능하나 가급적 사용X
- 둘 이상의 컬렉션을 페치 조인할 수 없다.
- 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.
- 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함
- 실무에서의 대부분의 성능문제는
N+1
문제이고, 다시 이들 중 대부분은fetch join
으로 해결 가능하다. - 여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 한다면, 페치 조인 보다는 일반 조인을 사용하고 필요한 데이터들만 조회해서 DTO로 반환하는 것이 효과적
엔티티 직접 사용
- JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용
Named 쿼리
@Entity
@NamedQuery(
name = "Member.findByUsername",
query = "select m from Member m where m.username = :username")
public class Member {
...
}
- 미리 정의해서 이름을 부여해두고 사용하는 JPQL
- 정적 쿼리
- 애플리케이션 로딩 시점에 초기화 후 재사용
- 애플리케이션 로딩 시점에 쿼리를 검증
- 같은 방식을 실무에서는 Spring Data JPA로 구현한다. (더 깔끔하게)
벌크 연산
- 쿼리 한 번으로 여러 테이블 로우 변경(엔티티)
excuteUpdate()
의 결과는 영향받은 엔티티 수 반환UPDATE
,DELETE
지원
주의
- 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리
- 방법 1) 벌크 연산을 먼저 실행
- 방법 2) 벌크 연산을 수행 후 영속성 컨텍스트 초기화
Leave a comment