본문 바로가기
JPA/JPA

[JPA] JPQL - 조인(Join)

by 걸어가는 신사 2022. 1. 7.

1. 내부 조인 (Inner Join)

  • INNER JOIN을 사용한다.
  • INNER 생략 가능하다.
String query = "select m from Member m join m.team t where t.name = :teamName";
List<Member> members = em.createQuery(query, Member.class)
	.setParameter("teamName", "teamA")
	.getResultList();
  • JPQL 조인의 가장 큰 특징은 연관 필드(m.team)를 사용한다는 것이다.
    • 연관 필드란 다른 엔티티와 연관관계를 가지기 위해 사용하는 필드를 말한다.
  • from Member m :
    • 회원을 선택하고 m이라는 별칭을 주었다.
  • Member m join m.team t : 
    • 회원이 가지고 있는 연관 필드로 팀과 조인한다. 조인한 팀에는 t라는 별칭을 주었다.

* 주의

String query = "select m from Member m join Team t"; //잘못된 JPQL 조인, 오류 발생
  • JPQL 조인을 SQL 조인처럼 사용하면 문법 오류가 발생한다.
  • JPQL은 JOIN 명령어 다음에 조인할 객체의 연관 필드를 사용한다.

 

2. 외부 조인 (Outer Join)

  • 기능상 SQL의 외부 조인과 같다.
  • OUTER는 생략 가능하다.
String query = "SELECT m from Member m LEFT OUTER JOIN m.team t";
List<Member> members = em.createQuery(query, Member.class)
	.getResultList();

 

3. 컬렉션 조인 (Collection JOIN)

  • 일대다 관계나 다대다 관계처럼 컬렉션을 사용하는 곳에 조인하는 것을 컬렉션 조인이라 한다.
  • [회원 -> 팀]으로의 조인은 다대일 조인이면서 단일 값 연관 필드(m.team)를 사용한다.
  • [팀 -> 회원]은 반대로 일대다 조인이면서 컬렉션 값 연관 필드(m.members)를 사용한다.
String query = "SELECT m,t FROM Team t LEFT JOIN t.members m";
List<Object[]> result = em.createQuery(query).getResultList();
for (Object[] objects : result) {
	Member member = (Member) objects[0];
	Team team = (Team) objects[1];
}
  • Team t LEFT JOIN t.members m : 
    • 팀과 팀이 보유한 회원 목록을 컬렉션 값 연관 필드로 외부 조인했다.

 

컬렉션 조인 시 JOIN 대신에 IN을 사용할 수 있는데, 기능상 JOIN과 같지만 컬렉션일 때만 사용할 수 있다.
과거 EJB 시절의 유물이고 특별한 장점도 없으므로 JOIN 명령어를 사용하자.

 

4. 세타 조인 (Theta Join)

  • 세타 조인은 내부 조인만 지원한다.
  • 세타 조인을 사용하면 전혀 관계없는 엔티티도 조인할 수 있다.
String query = "select count(m) from Member m, Team t where m.username = t.name";
Object result = em.createQuery(query).getSingleResult();
  • Member.username과 Team.name을 조인한다.
  • SQL에서 CROSS JOIN이 일어난다.

 

5. ON 절

(1) 조인 대상 필터링

//JPQL
String query = "SELECT m,t FROM Member m LEFT JOIN m.team t ON t.name='teamA'";
List<Object[]> resultList = em.createQuery(query).getResultList();
//SQL
SELECT m.*, t.* FROM Member m
LEFT JOIN Team t ON m.TEAM_ID=t.id and t.name='A'
  • 조인 시점에 조인 대상을 필터링한다.

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

//JPQL
String query = "SELECT m,t FROM Member m LEFT JOIN Team t ON m.username = t.name";
List<Object[]> resultList = em.createQuery(query).getResultList();
//SQL
SELECT m.*, t.* FROM Member m
LEFT JOIN Team t ON m.username = t.name

 

반응형

댓글