0. 개요
- JPQL에서 Join을 사용하는 방법에 대해서 알아보자.
1. Join의 종류
a) 내부 조인(inner join)
- 내부 조인은 INNER JOIN 키워드를 사용한다.
- 내부 조인은 JOIN의 기본 설정(= default)이다.
- 그러므로 그냥 JOIN 키워드만 사용하더라도 내부 조인을 수행한다.
- 내부 조인은 두 테이블을 조인할 때, 매칭되는 데이터가 존재하는 데이터만을 출력한다.
- 예를 들어, 테이블 A에는 A, B, C가 있고 테이블 B에는 A, B만 존재한다고 가정해보자.
- 내부 조인을 사용하는 경우, 조인 결과가 A, B만 출력된다.
- 즉, C와는 매칭되는 데이터가 없으므로 C는 출력되지 않는다.
- 다음 예시 코드를 보자.
SELECT p FROM Player p JOIN p.team t WHERE p.age >= 30;
b) 외부 조인(Outer join)
- 외부 조인은 LEFT JOIN 또는 RIGHT JOIN 키워드를 사용한다.
- 외부 조인은 두 테이블을 조인할 때, 매칭되는 데이터가 없더라도 모든 데이터를 출력한다.
- 이때 어떤 테이블을 기준으로 설정하냐에 따라서 LEFT 또는 RIGHT JOIN이 결정된다.
- 예를 들어, 테이블 A에는 A, B, C가 있고 테이블 B에는 A, B, D가 존재한다고 가정해보자.
- LEFT JOIN을 수행하는 경우, 테이블 A가 기준이 된다.
- 그러므로 조인 결과로 A, B, C를 출력한다.
- 반대로 RIGHT JOIN을 수행하는 경우, 테이블 B가 기준이 된다.
- 그러므로 조인 결과로 A, B, D를 출력한다.
- 다음 예시 코드를 보자.
- 외부 조인을 명시할 때, Outer 키워드는 생략 가능하다.
SELECT p FROM Player p LEFT JOIN p.team t WHERE p.age >= 30;
c) 세타 조인(Theta join)
- 세타 조인은 연관성이 없는 두 테이블을 조인하는 방법이다.
- WHERE 절의 조건을 JOIN 기준(= 연관성)으로 사용하여, 기존에 연관 관계가 없어도 Join 할 수 있다.
- 다만, 세타 조인은 내부 조인만 가능하다.
- 세타 조인은 Cross Join 이라 불리기도 한다.
- 다음 예시 코드를 보자.
SELECT p FROM Player p, Team t WHERE p.age > 30;
2. ON 절
a) ON의 역할
- ON 절은 다음 2가지 역할을 가진다.
→ JOIN 대상을 필터링 한다. (JPA 2.1부터 지원)
→ 연관 관계가 없는 객체와 외부 조인이 가능하다. (Hibernate 5.1부터 지원)
b) JOIN 대상을 필터링 한다.
- 다음 코드를 살펴보자.
SELECT p FROM Player p LEFT JOIN p.team t ON t.name = "ManUnited";
- 위의 쿼리는 Player와 Team을 조인하면서, Team의 이름이 "ManUnited"인 데이터를 가져오라는 의미다.
- 여기서 중요한 부분은 Team의 데이터를 가져올 때, name이 "ManUnited"인 데이터만 가져온다는 것이다.
- 즉, 대상이 되는 데이터를Join을 수행하기 전에 미리 필터링하는 것이다.
c) 외부 조인이 가능하다.
- 앞서 설명한 세타 조인은 내부 조인 방식만 가능하다고 하였다.
- 그러나 ON 절이 적용되면서 객체 간의 연관 관계가 없이도 외부 조인이 가능하다.
- 즉, ON 절을 사용하면 연관 관계 없이 외부 조인을 할 수 있다.
- Player 객체와 Team 객체 사이에 연관 관계가 없더라도 다음과 같이 외부 조인이 가능하다.
SELECT p FROM Player p LEFT JOIN Team t ON p.name = t.name;
3. Join 사용 시 주의 사항
a) 연관 관계를 형성하자.
- 세타 조인을 사용하면 객체 간 연관 관계가 없더라도 JOIN이 가능하다.
- 그러나 정석대로라면 JOIN을 수행하는 객체 간의 연관 관계를 형성하는 것이 옳다.
- 즉, JOIN을 할 때에는 객체 간의 연관 관계를 형성하는 것을 권장한다.
b) FetchType.LAZY
- 두 객체를 JOIN 하는 경우, 객체 내부에 연관 관계가 형성되어 있어야 한다.
- 그런데 만약 이 관계가 ManyToOne 또는 OneToMany 관계라면, 반드시 FetchType.LAZY를 설정해야한다.
- 위의 예시에서 Player 객체와 Team 객체를 조인하는 경우, Player 객체는 다음과 같이 정의되어 있어야 한다.
- 지연 로딩에 관한 내용은 이전 포스팅에서 정리하였다.
c) 파라미터 바인딩을 사용하자.
- WHERE 또는 ON 키워드를 통해 조건을 작성할 때에는 파라미터 바인딩을 사용하는 것을 권장한다.
- 파라미터 바인딩은 이전 포스팅에서 정리하였다.
'Back-end > JPA 개념' 카테고리의 다른 글
28. JPQL - case 식 (0) | 2022.04.28 |
---|---|
27. JPQL - 서브 쿼리 & 타입 표현 (0) | 2022.04.27 |
25. JPQL - 페이징 (0) | 2022.04.25 |
24. JPQL - 프로젝션(Projection, Select) (0) | 2022.04.22 |
23. JPQL - 기본 기능(파라미터 바인딩, 결과 조회, 쿼리의 종류) (0) | 2022.04.21 |
댓글