JPQL - 페치 조인(fetch join)

HUSII·2023년 7월 10일
0

JPA

목록 보기
2/7

JPQL에서 성능 최적화를 위해 제공하는 기능
연관된 엔티티나 컬렉션을 SQL 한번에 함께 조회하는 기능

명령어 [left] join fetch


페치조인의 특징

페치 조인을 사용할 때만 연관된 엔티티도 함께 조회(즉시로딩 - 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함)

이 기능이 너무 중요하다. 기존 지연로딩에서 발생했던 문제들을 대부분 해결해준다.

페치 조인은 객체 그래프를 SQL 한번에 조회하는 개념


엔티티 페치 조인

ToOne(ManyToOne, OneToOne) 연관관계를 페치조인할때의 경우
해당 엔티티와 관련된 엔티티를 함께 조회해 준다

EX)
MEMBER - {1,'han1', 3(FK)}, {2,'han2', 3(FK)}, {3,'han3',4(FK)}
TEAM - {3,'team1'}, {4,'team2'} 일때
select m from member m join fetch m.team(JPQL)의 결과

member_idusernameteam_id(FK)team_idteam_name
1han133team1
2han233team1
3han344team2

-> 기존 멤버의 정보에서 team의 정보까지 함께 조회됐다.

SQL에서는
select m.*, t.* from member m join team t on m.team_id=t.team_id로 입력된다.


컬렉션 페치 조인

ToMany 연관관계를 페치조인할때의 경우
해당 엔티티와 연관된 컬렉션을 함께 조회해준다.

select t from team t join fetch t.members(JPQL)의 결과
SQL에서는 select t.*, m.* from team t join member m on m.team_id=t.team_id

team_idteam_namemember_idusernameteam_id(FK)
3team11han13
3team12han23
4team23han34

기존 엔티티(TEAM)의 데이터가 뻥튀기된다.
페치조인없이 team의 정보만 조회했을 경우 team1, team2 두개의 데이터만 조회되지만, t.members 컬렉션을 페치 조인해서 team의 데이터가 뻥튀기 되었다.

뻥튀기되는 이유는 team과 member의 연관관계가 OneToMany이기 때문
-> 하나의 팀을 골랐을때 여러명의 멤버가 나올 수 있다
JPQL의 페치조인은 그냥 연관관계가 있는 필드(지연로딩)에 값을 넣어주는 일만 할뿐
(결과는 SQL의 기본 조인과 같다)


페치조인과 distinct

SQL의 DISTINCT는 중복된 결과를 제거하는 명령
JPQL의 DISTINCT 2가지 기능 제공

  • SQL에 DISTINCT를 추가
  • 애플리케이션에서 엔티티 중복 제거

sql에서 distinct는 페치조인의 중복된 결과를 거의 제거하지 못한다. 대부분 애플리케이션에서 엔티티 중복을 제거해준다.


페치조인과 일반조인

일반 조인 실행시 연관된 엔티티를 함께 조회하지 않음
select t from team t join member m(JPQL)의 결과

team_idteam_name
3team1
3team1
4team2

member의 정보는 조회되지 않았고, member 엔티티때문에 team의 정보만 뻥튀기되었다. (TEAM 엔티티기준)

만약 JPQL에 다른 엔티티의 필드를 직접 입력해서 쿼리를 보내면 원하는대로 가져오지만, 직접 attribute를 지정해주기 때문에 나중에 못쓸확률 높다

하지만 일반 join은 fetch join보다 조금 더 성능 최적화가 이루어진다는 장점이 있다.


페치조인의 한계점

페치 조인 대상에는 별칭을 줄 수 없다.
둘 이상의 컬렉션은 페치 조인 할 수 없다.
컬렉션을 페치 조인하면 페이징 API(setFirstResult, setMaxResults)를 사용할 수 없다.

여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하면, 페치 조인 보다는 일반 조인을 사용하고 필요 한 데이터들만 조회해서 DTO로 반환하는 것이 효과적

profile
공부하다가 생긴 궁금한 것들을 정리하는 공간

0개의 댓글