오봉이와 함께하는 개발 블로그

Querydsl - 조인 (on 절) 본문

BE/JPA

Querydsl - 조인 (on 절)

오봉봉이 2022. 9. 17. 23:08
728x90

조인 - on절

  • ON절을 활용한 조인(JPA 2.1부터 지원)
    • 조인 대상 필터링
    • 연관관계 없는 엔티티 외부조인

1. 조인 대상 필터링

  • 회원과 팀을 조인하면서, 팀 이름이 teamA인 팀만 조인, 회원은 모두 조회
/**
 * 예) 회원과 팀을 조인하면서, 팀 이름이 teamA인 팀만 조인, 회원은 모두 조회
 * JPQL : SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'teamA'
 * SQL : SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.TEAM_ID=t.id and t.name='teamA'
 */
@Test
void join_on_filtering() {
    List<Tuple> result = queryFactory
            .select(member, team)
            .from(member)
            .leftJoin(member.team, team)
            .on(team.name.eq("teamA"))
            .fetch();
    for (Tuple tuple : result) {
        System.out.println("tuple = " + tuple);
    }
}

결과

tuple = [Member(id=3, username=member1, age=10), Team(id=1, name=teamA)]
tuple = [Member(id=4, username=member2, age=20), Team(id=1, name=teamA)]
tuple = [Member(id=5, username=member3, age=30), null]
tuple = [Member(id=6, username=member4, age=40), null]
select member1, team
from Member member1
left join member1.team as team with team.name = 'teamA'1

select member0_.member_id as member_i1_1_0_, team1_.team_id as team_id1_2_1_, member0_.age as age2_1_0_, member0_.team_id as team_id4_1_0_, member0_.username as username3_1_0_, team1_.name as name2_2_1_
from member member0_
left outer join team team1_
on member0_.team_id=team1_.team_id
and (team1_.name=NULL);

on절을 활용해 조인 대상을 필터링 할 때, 외부조인이 아니라 내부조인(inner join)을 사용하면, where절에서 필터링 하는 것과 기능이 동일하다.
따라서 on절을 활용한 조인 대상 필터링을 사용할 때, 내부조인 이면 익숙한 where절로 해결하고, 정말 외부조인이 필요한 경우에만 이 기능을 사용하자.

2. 연관관계 없는 엔티티 외부 조인

/**
 * 2. 연관관계 없는 엔티티 외부 조인
 * 예)회원의 이름과 팀의 이름이 같은 대상 외부 조인
 * JPQL: SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
 * SQL: SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.username = t.name */
@Test
void join_on_no_relation() {
    em.persist(new Member("teamA"));
    em.persist(new Member("teamB"));
    List<Tuple> result = queryFactory
            .select(member, team)
            .from(member)
            .leftJoin(team)
            .on(member.username.eq(team.name))
            .fetch();
    for (Tuple tuple : result) {
        System.out.println("tuple = " + tuple);
    }
}

결과

tuple = [Member(id=3, username=member1, age=10), null]
tuple = [Member(id=4, username=member2, age=20), null]
tuple = [Member(id=5, username=member3, age=30), null]
tuple = [Member(id=6, username=member4, age=40), null]
tuple = [Member(id=7, username=teamA, age=0), Team(id=1, name=teamA)]
tuple = [Member(id=8, username=teamB, age=0), Team(id=2, name=teamB)]
select member1, team
from Member member1
left join Team team with member1.username = team.name

select member0_.member_id as member_i1_1_0_, team1_.team_id as team_id1_2_1_, member0_.age as age2_1_0_, member0_.team_id as team_id4_1_0_, member0_.username as username3_1_0_, team1_.name as name2_2_1_
from member member0_
left outer join team team1_
on (member0_.username=team1_.name);
  • 하이버네이트 5.1부터 on을 사용해서 서로 관계가 없는 필드로 외부 조인하는 기능이 추가되었다.
    • 물론 내부 조인도 가능하다.
  • 주의! 문법을 잘 봐야 한다.
    • leftJoin() 부분에 일반 조인과 다르게 엔티티 하나만 들어간다.
      • 일반조인 : leftJoin(member.team, team)
      • on조인 : from(member).leftJoin(team).on(xxx)
인프런 김영한 지식공유자님 강의 : 실전! Querydsl
728x90

'BE > JPA' 카테고리의 다른 글

Querydls - 서브 쿼리  (0) 2022.09.18
Querydsl - 조인 (페치 조인)  (0) 2022.09.17
Querydsl - 조인 (기본 조인)  (0) 2022.09.17
Querydsl - 집합  (0) 2022.09.16
Querydsl - 페이징  (0) 2022.09.16
Comments