🖊 경로 표현식
- 상태 필드 : 단순히 값을 저장하기 위한 필드 (ex: m.username)
=> 경로 탐색의 끝, 탐색 X
- 연관 필드 : 연관관계를 위한 필드
=>단일 값 연관 경로(m.team.~) : 묵시적 내부 조인 발생, 탐색 O
=>컬렉션 값 연관 경로(t.members) : 묵시적 내부 조인 발생, 탐색 X
- 명시적 조인 : select m from Member m join m.team
- 묵시적 조인 : select m.team from Member m
- 묵시적 조인은 권장되지 않는다.
🖊 패치 조인(fetch join)
- SQL 조인 종류 X
- JPQL에서 성능 최적화를 위해 제공하는 기능
- 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
- join fetch 명령어 사용
🖊 엔티티 패치 조인
한 번에 회원을 조회하면서 연관된 팀을 함께 조회하고 싶은 상황
JPQL
SELECT m FROM Member m join fetch m.team
SQL
SELECT M.*, T.* FROM MEMBER M INNER JOIN TEAM T ON M.TEAM_ID=T.ID
🖊 컬렉션 패치 조인
JPQL
select t from Team t join fetch t.members
SQL
select T.*, M.* from TEAM T inner join MEMBER M ON T.ID=M.TEAM_ID
- 결과가 중복되는 것을 막기위해 SQL과 JPQL은 DISTINCT를 제공한다.
(모든 속성 값이 같아야 중복이 제거됨)
- JPQL은 어플리케이션 레벨에서 엔티티의 중복 제거를 함께 해준다.
🤔 일반 조인과 패치 조인의 차이?
- 일반 조인은 기본적으로 지연 로딩이기 때문에 연관된 엔티티를 함께 조회하지 않는다.
- 일반 조인은 SELECT 절에 지정한 엔티티만 조회한다.
- 패치 조인은 객체 그래프를 SQL 한 번에 조회하는 개념
N+1 문제를 어떻게 해결하나 싶었는데 이런 방법이 있구나 싶다.
패치 조인의 한계
- 패치 조인은 기본적으로 모든 연관 그래프를 가지고 온다는 개념이다.
- 패치 조인 대상에는 별칭을 줄 수 없다. (where m.~ 이런 것 쓰면 안 됨)
- 둘 이상의 컬렉션은 패치 조인 할 수 없다.
- 컬렉션을 패치 조인하면 페이징 API를 사용할 수 없다.