[인프런 김영한] JPA - 조인

2021. 2. 16. 17:25프로그래밍 언어/Spring Framework

[인프런 김영한] JPA - 조인


해당 글은 인프런 김영한강사님의 영상을 보고 정리한 글입니다.

김영한 인프런 : www.inflearn.com/users/@yh

 

인프런 - 김영한의 강의들을 만나보세요.

우아한형제들 개발 팀장 (전: 카카오, SK플래닛) 저서: 자바 ORM 표준 JPA 프로그래밍

www.inflearn.com


▣ inner join

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
member.setTeam(team);

em.persist(member);

em.flush();
em.clear();

String query = "select m from Member m inner join m.team";
List<Member> resultList = em.createQuery(query, Member.class).getResultList();


// 실행
Hibernate: 
    /* select
        m 
    from
        Member m 
    inner join
        m.team */ select
            member0_.id as id1_0_,
            member0_.age as age2_0_,
            member0_.TEAM_ID as team_id4_0_,
            member0_.username as username3_0_ 
        from
            Member member0_ 
        inner join
            Team team1_ 
                on member0_.TEAM_ID=team1_.TEAM_ID
Hibernate: 
    select
        team0_.TEAM_ID as team_id1_3_0_,
        team0_.name as name2_3_0_ 
    from
        Team team0_ 
    where
        team0_.TEAM_ID=?

| 어? select team_id, name from team where team_id=? 아래 쿼리는 뭘까?

내가 원하지 않는 쿼리가 실행이 되었다.

 -> Member의 Team(ManyToOne)이 EAGER이기 때문이다.

 

Member

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;

 

 

 

▣ left join

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setAge(10);
member.setTeam(team);

em.persist(member);

em.flush();
em.clear();

String query = "select m from Member m left join m.team";
List<Member> resultList = em.createQuery(query, Member.class).getResultList();


//실행 
Hibernate: 
    /* select
        m 
    from
        Member m 
    left join
        m.team */ select
            member0_.id as id1_0_,
            member0_.age as age2_0_,
            member0_.TEAM_ID as team_id4_0_,
            member0_.username as username3_0_ 
        from
            Member member0_ 
        left outer join
            Team team1_ 
                on member0_.TEAM_ID=team1_.TEAM_ID

 

 

▣ theta join

- 막조인

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setUsername("TeamA"); // theat join 예제
member.setAge(10);
member.setTeam(team);

em.persist(member);

em.flush();
em.clear();

String left_join = "select m from Member m left join m.team";
String inner_join = "select m from Member m inner join m.team";
String theta_join = "select m from Member m, Team t where m.username = t.name";
List<Member> resultList = em.createQuery(theta_join, Member.class).getResultList();


// 실행
Hibernate: 
    /* select
        m 
    from
        Member m,
        Team t 
    where
        m.username = t.name */ select
            member0_.id as id1_0_,
            member0_.age as age2_0_,
            member0_.TEAM_ID as team_id4_0_,
            member0_.username as username3_0_ 
        from
            Member member0_ cross 
        join
            Team team1_ 
        where
            member0_.username=team1_.name

 

 


▣ JPA 2.1부터 ON절을 활용한 JOIN문 쿼리를 사용할 수 있다.

 * 조인 대상 피렅링

 * 연관관계 없는 Entity 외부 조인(하이버네이트 5.1부터)

 

◈ 조인 대상 필터링

// 회원과 팀을 조인하면서
// 팀 이름이 A인 팀만 조회

// SQL
SELECT m.*, t.* 
FROM Member m 
LEFT JOIN Team t on m.TEAM_ID = t.id
and t.name = 'A'

// JPQL
SELECT m, t
FROM Member m
LEFT JOIN m.team t on t.name = 'A'

// 예제
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setUsername("TeamA"); // theat join 예제
member.setAge(10);
member.setTeam(team);

em.persist(member);

em.flush();
em.clear();

String left_join = "select m from Member m left join m.team";
String inner_join = "select m from Member m inner join m.team";
String theta_join = "select m from Member m, Team t where m.username = t.name";
List<Member> resultList = em.createQuery(theta_join, Member.class).getResultList();

// 실행문
Hibernate: 
    /* select
        m 
    from
        Member m 
    left join
        m.team t 
            on t.name = 'A' */ select
                member0_.id as id1_0_,
                member0_.age as age2_0_,
                member0_.TEAM_ID as team_id4_0_,
                member0_.username as username3_0_ 
        from
            Member member0_ 
        left outer join
            Team team1_ 
                on member0_.TEAM_ID=team1_.TEAM_ID 
                and (
                    team1_.name='A'
                )

| JPQL에서의 ON은 Team의 name이 'A'인것만 하고 싶다의 의미다.

 

 

◈ 연관관계 없는 Entity 외부 조인

// 회원의 이름과 팀의 이름이 같은 대상 외부 조인

// SQL
SELECT m.*, t.* 
FROM Member m 
LEFT JOIN Team t ON m.username = t.name

// JPQL
SELECT m, t
FROM Member m
LEFT JOIN Team t on m.username = t.name


// 예제
Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setUsername("member1");
member.setUsername("TeamA"); // theat join 예제
member.setAge(10);
member.setTeam(team);

em.persist(member);

em.flush();
em.clear();

String leftJoin = "select m from Member m left join Team t on m.username = t.name";
List<Member> resultList = em.createQuery(leftJoin, Member.class).getResultList();

// 실행
Hibernate: 
    /* select
        m 
    from
        Member m 
    left join
        Team t 
            on m.username = t.name */ select
                member0_.id as id1_0_,
                member0_.age as age2_0_,
                member0_.TEAM_ID as team_id4_0_,
                member0_.username as username3_0_ 
        from
            Member member0_ 
        left outer join
            Team team1_ 
                on (
                    member0_.username=team1_.name
                )