본문 바로가기
데이터 접근 기술/JPA

[JPA] JPQL JOIN

by oncerun 2021. 1. 31.
반응형

JPQL 조인은 SQL 조인과 기능은 같고 문법만 약간의 차이가 있다.

 

내부 조인

 내부 조인은 INNER JOIN을 사용하며 INNER은 생략 가능하다.

 

JPQL을 사용해 회원과 팀을 내부 조인하는 예시를 들고 실제 쿼리가 어떻게 나가는지에 대해서 비교해보자

 

JPQL

 SELECT m FROM Member m JOIN m.team t WHERE t.name = '팀A'

팀 A인 회원을 조호하는 JPQL이다. 

생성된 내부 조인 SQL문을 보자

SELECT
	M.ID AS ID,
    M.AGE AS AGE,
    M.TEAM_ID AS TEAM_ID
    M.NAME AS NAME
FROM
	MEMBER M INNER JOIN TEAM T ON M.TEAM_ID = T.ID
WHERE
	T.NAME = '팀A'

 

여기서 큰 특징은 JPQL은 연관 필드를 사용한다는 것인데, m.team을 사용해 팀과 매칭 한 것을 볼 수 있다.

만약 TEAM이라는 엔티티를 대신 사용한다면 오류가 발생한다 JPQL은 JOIN 명령어 다음에 조인할 객체의 연관 필드를 사용하기 때문이다.

 

 

외부 조인은 다음과 같이 사용한다.

 

SELECT m FROM Member m LEFT JOIN m.team t

보통 OUTTER라는 키워드는 생략한다.  생성된 SQL문을 보자

SELECT M.* 
FROM
	MEMBER M LEFT OUUTER JOIN TEAM T ON M.TEAM_ID = T.ID
WHERE
 T.NAME ='팀A'

 

컬렉션 조인이란 일대다 관계나 다대다 관계처럼 컬렉션을 사용하는 곳에 조인하는 것을 컬렉션 조인이라 한다.

팀 -> 회원 경우 일대다 조인이면서 팀 연관 필드에 컬렉션 값 연관 필드(t.members)를 사용한다.

 

SELECT t, m FROM TEAM t LEFT JOIN t.members m

 

여기선 t left join t. members는 팀과 팀이 보유한 회원 목록을 컬렉션 값 연관 필드로 외부 조인했다.

 

 

세타 조인(cross join)

 

where 절을 사용해서 세타 조인을 할 수 있다. 세타 조인은 내부 조인만 지원하며 서로 다른 엔티티를 조회할 수 있다.

 

Fetch Join

페치 조인은 JPQL에서 성능 최적화를 위해 제공하는 기능이다. 이 조인은 연관된 엔티티나 컬렉션을 한 번에 같이 조회하는 기능인데 join fetch 명령어로 사용할 수 있다.

 1) 엔티티 페치 조인

 페치 조인을 사용해 회원 엔티티를 조회하면서 연관된 팀 엔티티도 함께 조회하는 JPQL을 보자

 

SELECT m FROM Member m join fetch m.team

 

회원과 팀을 함께 조회한다. 참고로 fetch조인은 m.team다음에 별칭을 사용할 수 없다.

 

실행된 SQL문은 다음과 같다.

 

SELECT M.*,T.* 

FROM MEMBER M

INNER JOIN TEAM T ON M.TEAM_ID = T.ID

 

이 경우에는 지연 로딩 기능을 사용하지 않고 즉시 로딩을 사용하기 때문에 회원 엔티티가 준영속 상태가 되어 연관된 엔티티인 팀을 탐색할 수 있다.

 

 2) 컬렉션 페치 조인은 일대다 관계에서 사용하며 이경우에는 조회 횟수가 다에 맞춰져서 증가한다.

 

팀 테이블에서 팀 A는 하나의 로우지만 MEMBER에는 여러 명이 팀 A에 속한다고 하자. 이 경우 Team과 Member조인했을 때 팀 A인 멤버들이 여러 명이 조회되기에 조회 값이 하나가 아닌  같은 팀이 여러 건이 발생한다. 이러한 중복을 제거하기 위해선 DISTINCT 명령어를 사용한다.

 

JPQL을 사용할 때 고려해야 할 점이 JPQL은 결과를 반환할 때 연관관계까지 고려하지 않고 조회한다. 단지 SELECT절에 지정한 엔티티만 조회할 뿐이다.

 

JPA를 사용하면 기본적으로 글로벌 로딩 전략을 사용하여 엔티티에 fetch전략을 적용해 보았을 것이다

ex) @OneToMany(fetch = FetchType.LAZY) 하지만 JPQL에서 페치 조인을 사용하면 페치 조인을 적용을 우선시한다.

반응형

'데이터 접근 기술 > JPA' 카테고리의 다른 글

[JPA] JPA 기본 정리  (0) 2021.04.11
[JPA] 벌크 연산  (0) 2021.01.31
[JPA] JPQL 기본 문법과 SELECT 절  (0) 2021.01.31
[JPA] JPQL 소개  (0) 2021.01.30
[JPA] 즉시 로딩과 지연 로딩  (0) 2021.01.28

댓글