본문 바로가기
Back-end/JPA 개념

26. JPQL - 조인

by devraphy 2022. 4. 26.

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 키워드를 통해 조건을 작성할 때에는 파라미터 바인딩을 사용하는 것을 권장한다.

- 파라미터 바인딩은 이전 포스팅에서 정리하였다.

 

댓글