QMember m = QMember.member;
QTeam team = QTeam.team;
join(m.team, team)
join(조인할대상, 별칭으로사용할Q타입)
@Test
public void join(){
List<Member> result = query.selectFrom(m).join(m.team, t).where(t.name.eq("teamA")).fetch();
assertThat(result).extracting("username").containsExactly("member1", "member2");
}
m이 가지고 있는 team을 join해서 가지고 오고, 위에 QTeam = QTeam.team이라고 해놨다. 그 Q클래스를 별칭용 클래스로 쓸 것이다.
extracting은 적출 이란 뜻인데, 해당 문자열인 이름의 필드를 찾아 Collection 형식으로 만드는 모양이다.
거기에 containsExactly
https://qwefdg3.tistory.com/870
결과는 문제없이 통과했다.
/* select
member1
from
Member member1
inner join
member1.team as team
where
team.name = ?1 */ select
m1_0.member_id,
m1_0.age,
m1_0.team_id,
m1_0.username
from
member m1_0
join
team t1_0
on t1_0.team_id=m1_0.team_id
where
t1_0.name=?
이렇게 inner join으로 나간다. join(on에들어갈조건식)이기도 한 것 같다.
join()은 DB에서 처럼 inner join이고, left join, right join도 있다.
List<Member> result = query.selectFrom(m).leftJoin(m.team, t).where(t.name.eq("teamA")).fetch();
/* select
member1
from
Member member1
left join
member1.team as team
where
team.name = ?1 */ select
m1_0.member_id,
m1_0.age,
m1_0.team_id,
m1_0.username
from
member m1_0
left join
team t1_0
on t1_0.team_id=m1_0.team_id
where
t1_0.name=?
left join도 이렇게 의도했던 대로 잘 나간다.
on을 따로도 할 수 있는데, 그건 다음 장
세타 조인.
전혀 연관관계가 없는 것을 join 할 때.
@Test
public void theta_join(){
em.persist(new Member("teamA"));
em.persist(new Member("teamB"));
em.persist(new Member("teamC"));
List<Member> result = query.select(m).from(m, t).where(m.username.eq(t.name)).fetch();
assertThat(result).extracting("username").containsExactly("teamA", "teamB");
}
그냥 임의로 Member이름을 teamA, B 등으로 등록했다.
쿼리 메소드를 보면
from에서 m, t
where에서 조건 후 가져온다.
from m,t는 m과 t를 곱하기, 즉 데이터 뻥튀기가 일어난다.
실제로
List<Tuple> result = query.select(m, t).from(m, t).fetch();
이렇게 해 보면 member 4개, team 2개 해서 사이즈가 8개가 나온다. member하나당 team이 2개씩 붙어서. 그러니까 모든 경우의 수와 비슷하다.
그러니까, 일단 from에서 m, t 가져와서 쫙 모든 경우의 수 리스트를 나열한 다음에, where의 조건으로 거기서 뽑는 것이다.
물론 DB 내부에서 알아서 최적화는 한다.
/* select
member1
from
Member member1,
Team team
where
member1.username = team.name */ select
m1_0.member_id,
m1_0.age,
m1_0.team_id,
m1_0.username
from
member m1_0,
team t1_0
where
m1_0.username=t1_0.name
나가는 쿼리.
List<Tuple> result = query.select(m, t).from(m, t).fetch();
이거의 경우
/* select
member1,
team
from
Member member1,
Team team */ select
m1_0.member_id,
m1_0.age,
m1_0.team_id,
m1_0.username,
t1_0.team_id,
t1_0.name
from
member m1_0,
team t1_0
그런데, 이렇게 세타 조인의 경우 아쉬운 점이, 보이는 바와 같이
left join이나 right join 등, outer join, 즉 외부조인이 안된다.
과거에는 안됐는데, 이제 연관관계가 없는 테이블을 on절을 이용해서 left join이 가능하다.
'스프링데이터 + JPA > QueryDSL' 카테고리의 다른 글
16. join fetch (0) | 2023.11.29 |
---|---|
15. join on (0) | 2023.11.29 |
13. 그룹 (0) | 2023.11.29 |
12. 페이징 (0) | 2023.11.28 |
11. 정렬 (0) | 2023.11.28 |