Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 알고리즘
- db
- java
- 김영한
- 백준
- Android
- Exception
- pointcut
- kotlin
- 인프런
- spring
- transaction
- AOP
- jpa
- 스프링 핵심 원리
- QueryDSL
- 스프링
- Greedy
- Spring Boot
- springdatajpa
- Proxy
- http
- Servlet
- 스프링 핵심 기능
- JPQL
- Thymeleaf
- JDBC
- 자바
- SpringBoot
- 그리디
Archives
- Today
- Total
개발자되기 프로젝트
Join 본문
1. 기본 조인
- 조인의 기본 문법은 첫 번째 파라미터에 조인 대상을 지정하고,
- 두 번째 파라미터에 별칭(alias)을 사용하여 Q타입을 지정.(QTeam.team)
@Override
public <P> Q join(EntityPath<P> target, Path<P> alias) {
return queryMixin.join(target, alias);
}
/**
* 팀A에 소속된 모든 회원 조회
*/
@Test
public void join(){
List<Member> result = queryFactory
.selectFrom(member)
.join(member.team, QTeam.team)
.where(team.name.eq("teamA"))
.fetch();
assertThat(result)
.extracting("username")
.containsExactly("member1", "member2");
}
select
member1
from
Member member1
inner join
member1.team as team
where
team.name = ?1 */ select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_
inner join
team team1_
on member0_.team_id=team1_.team_id
where
team1_.name=?
2. 세타조인
- 연관관계가 없는 둘을 조인시킴
- from 절에 여러 엔티티를 선택해서 세타 조인
- 외부 조인 불가능 다음에 설명할 조인 on을 사용하면 외부 조인 가능
/**
* 세타조인
* 회원의 이름이 팀 이름과 같은 회원을 조회
*/
@Test
public void theta_join(){
em.persist(new Member("teamA"));
em.persist(new Member("teamB"));
List<Member> result = queryFactory
.select(member)
.from(member, team)
.where(member.username.eq(team.name))
.fetch();
}
3. 조인 on 절
- 조인 대상 필터링
- 연관관계 없는 엔티티 외부 조인
3.1 조인 대상 필터링
- 회원과 팀을 조인하면서, 팀 이름이 teamA인 팀만 조인, 회원은 모두 조회\
- select m, t from Member m left join m.team t on t.name = 'teamA'
- left join이기 때문에 member는 다 가져오고 teamA가 아닌 경우는 null
/**
* 회원과 팀을 조인하면서, 팀 이름이 teamA인 팀만 조인, 회원은 모두 조회
* select m, t from Member m left join m.team t on t.name = 'teamA'
*/
@Test
public 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);
}
}
/* select
member1,
team
from
Member member1
left join
member1.team as team with team.name = ?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=?
)
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]
- on 절을 활용해 조인 대상을 필터링 할 때, 외부조인이 아니라 내부조인(inner join)을 사용하면,
- where 절에서 필터링 하는 것과 기능이 동일하다. 따라서 on 절을 활용한 조인 대상 필터링을 사용할 때,
- 내부조인 이면 익숙한 where 절로 해결하고, 정말 외부조인이 필요한 경우에만 이 기능을 사용하자.
- left join인 경우 값이 없어도 가져와야 할 경우가 있기 때문에 on절이 의미가 있음.
3.2 연관관계 없는 엔티티 외부 조인
- from에 바로 team을 넣음.-> id로 찾는게 아님
- 아래 예제는 연관관계가 아니어도 이름이 같은 경우에 조인함.--> 조건이 맞지 않으면 null
/**
* 연관관계 없는 엔티티 외부 조인
* 회원의 이름이 팀 이름과 같은 회원을 조회
*/
@Test
public 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);
}
}
/* 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
)
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)]
- 하이버네이트 5.1부터 on 을 사용해서 서로 관계가 없는 필드로 외부 조인하는 기능이 추가되었다.
- leftJoin() 부분에 일반 조인과 다르게 엔티티 하나만 들어감.
- 일반조인: leftJoin(member.team, team)
- on조인: from(member).leftJoin(team).on(xxx)
4. 페치조인
- join(), leftJoin() 등 조인 기능 뒤에 fetchJoin() 이라고 추가하면 된다.
@PersistenceUnit
EntityManagerFactory emf;
@Test
public void fetchJoin(){
em.flush();
em.clear();
Member findMember = queryFactory
.selectFrom(member)
.join(member.team, team).fetchJoin()
.where(member.username.eq("member1"))
.fetchOne();
//team이 이미 로딩된 엔티티 인지 확인
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam());
assertThat(loaded).as("페치 조임 미적용").isTrue();
}
/* select
member1
from
Member member1
inner join
fetch member1.team as team
where
member1.username = ?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_
inner join
team team1_
on member0_.team_id=team1_.team_id
where
member0_.username=?
5. GitHub : 210902 join
'인프런 > [인프런] QueryDsl' 카테고리의 다른 글
Case 문 (0) | 2021.09.02 |
---|---|
서브쿼리, SubQuery (0) | 2021.09.02 |
집합 (0) | 2021.09.01 |
페이징 (0) | 2021.09.01 |
정렬 (0) | 2021.09.01 |
Comments