JPA/JPA 기본

41. 조인

sdafdq 2023. 10. 31. 08:25

sql 조인이랑 거의 비슷한데, JPQL은 엔티티 중심으로 동작한다.

 

내부(inner) 조인

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

for (Member m : result) {
    System.out.println("result = " + m.getUsername());
    System.out.println("result = " + m.getTeam().getName());
}

inner는 생략이 가능하다.

내부 조인은 만약 team이 없으면 아예 member까지 나오지 않는다.

Hibernate: 
    /* select
        m 
    from
        Member m 
    inner join
        m.team t */ select
            m1_0.id,
            m1_0.age,
            m1_0.team_id,
            m1_0.username 
        from
            Member m1_0 
        join
            Team t1_0 
                on t1_0.id=m1_0.team_id

쿼리는 이렇게 나간다.

 

 

외부조인(outer)은

List<Member> result = em.createQuery("select m from Member m left outer join m.team t", Member.class)
        .getResultList();

for (Member m : result) {
    System.out.println("result = " + m.getUsername());
    System.out.println("result = " + m.getTeam().getName());
}

team이 없어도 team이 null로 나오고 데이터를 가져온다.

outer는 생략할 수 있다.

Hibernate: 
    /* select
        m 
    from
        Member m 
    left outer join
        m.team t */ select
            m1_0.id,
            m1_0.age,
            m1_0.team_id,
            m1_0.username 
        from
            Member m1_0

쿼리는 이렇게 나간다.

 

 

 

세타조인

이건 정말 연관관계가 없는 것을 가져오려고 할 때

List result = em.createQuery("select count(m) from Member m, Team t where m.username = t.name")
        .getResultList();

비즈니스 적으로는 정말 의미없긴 한데,

그냥 멤버의 이름과 팀 이름이 같은 경우의 count()를 가져옴.

둘이 연관관계가 없다고 가정하는거임. 현재환경에서 둘이 연관관계가 있기는 함.

여튼 select 해서 ,로 2개 불러오고 where로 조건

Hibernate: 
    /* select
        count(m) 
    from
        Member m,
        Team t 
    where
        m.username = t.name */ select
            count(m1_0.id) 
        from
            Member m1_0,
            Team t1_0 
        where
            m1_0.username=t1_0.name

 

 

 

 

on

JPQL에서도 JPA 2.1부터 (지금은 다 2.1 이상) on 지원

on은 조인 대상을 필터링 하는 거임.

 

또 on을 이용해 연관관계 없는 엔티티를 외부조인 가능(하이버네이트 5.1전까진 내부조인만 가능했었음.)

 

List<Member> result = em.createQuery("select m from Member m join m.team t on t.name = 'teamA'", Member.class)
        .getResultList();

이렇게. 그냥 join이니 내부조인,

Member를 가져오는데, team을 내부조인으로 가져오는데,

on 해서 team.name이 'teamA'인 것들만 가져오고 싶어.

Hibernate: 
    /* select
        m 
    from
        Member m 
    join
        m.team t 
            on t.name = 'teamA' */ select
                m1_0.id,
                m1_0.age,
                m1_0.team_id,
                m1_0.username 
        from
            Member m1_0 
        join
            Team t1_0 
                on t1_0.id=m1_0.team_id 
                and t1_0.name='teamA'

 

 

 

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

List result = em.createQuery("select m,t from Member m left join Team t on t.name = 'teamA'")
        .getResultList();
Hibernate: 
    /* select
        m,
        t 
    from
        Member m 
    left join
        Team t 
            on t.name = 'teamA' */ select
                m1_0.id,
                m1_0.age,
                m1_0.team_id,
                m1_0.username,
                t1_0.id,
                t1_0.name 
        from
            Member m1_0 
        left join
            Team t1_0 
                on t1_0.name='teamA'

이렇게 하면 m, t 둘다 가져와서 Object[] 배열에 담겨서 0이 Member, 1이 Team이 담김.

Object[] o = (Object[])result.get(0);
System.out.println("result = " + o[0]);

select m, t로 한번에 2쌍을 가져오는 거니.. Object[]에 m,t가 들어가고, 그게 데이터마다 List에 들어간 거.

여러 개 였으면 List에 여러 개 들어갔었을 거임.

 

 

 

'JPA > JPA 기본' 카테고리의 다른 글

43. JPA 타입 표현과 기타식  (0) 2023.10.31
42. 서브쿼리  (0) 2023.10.31
40. 페이징  (0) 2023.10.31
39. 프로젝션(select)  (0) 2023.10.30
38. JPQL 기본 문법  (0) 2023.10.30