-
[Spring] querydsl - joinSpring 2022. 1. 3. 23:16
기본 조인
@Test public void join() throws Exception { QMember member = QMember.member; QTeam team = QTeam.team; List<Member> result = queryFactory .selectFrom(member) .join(member.team, team) .where(team.name.eq("teamA")) .fetch(); assertThat(result) .extracting("username") .containsExactly("member1", "member2"); } }
join은 innerjoin과 같은 개념이다.
left join과 right join 모두 가능하다.
세타 조인
@Test public void theta_join() throws Exception { 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(); assertThat(result) .extracting("username") .containsExactly("teamA", "teamB"); }
from절에 여럿 엔티티를 선택해서 세타 조인을 한다.
조인 on절을 사용해 외부조인이 가능함.
조인 - on절
- On절을 활용한 조인
- 조인 대상 필터링
- 연관관계 없는 엔티티 외부 조인
조인 대상 필터링
@Test public void join_on_filtering() throws Exception { 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); } }
join() 첫 파라미터에 조인할 행을 넣어주고, 두번째 파라미터에 엔티티를 넣어주면 된다.
다만 innerjoin의 경우엔 on과 where의 차이가 없고, outer join인 경우 on절은 join의 조건이 되주어 null로 값이 남고, where의 경우 필터링이 되어버린다.
on과 where의 차이
//on절
t=[Member(id=3, username=member1, age=10), Team(id=1, name=teamA)]
t=[Member(id=4, username=member2, age=20), Team(id=1, name=teamA)]
t=[Member(id=5, username=member3, age=30), null]
t=[Member(id=6, username=member4, age=40), null]
//where절
t=[Member(id=3, username=member1, age=10), Team(id=1, name=teamA)]
t=[Member(id=4, username=member2, age=20), Team(id=1, name=teamA)]연관관계 없는 엔티티 외부 조인
@Test public void join_on_no_relation() throws Exception { 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("t=" + tuple); } }
연관관계 있는 상태와 차이점은 join함수 옆에 현재테이블의 조인컬럼이 안들어가고 엔티티만 들어간다.
fetch 조인
성능최적화를 위해 필요한 경우 즉시로딩을 해야할 때가 있다.
이때 fetchjoin을 쓰면 된다.
@PersistenceUnit EntityManagerFactory emf; @Test public void fetchJoinUse() throws Exception { em.flush(); em.clear(); Member findMember = queryFactory .selectFrom(member) .join(member.team, team).fetchJoin() .where(member.username.eq("member1")) .fetchOne(); boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam()); assertThat(loaded).as("페치 조인 적용").isTrue(); }
'Spring' 카테고리의 다른 글
[Spring] querydsl - 임의의 기준으로 정렬을 하고 싶다면 (0) 2022.01.05 [Spring] AssertJ 정리 (0) 2022.01.04 [Spring] querydsl - paging (0) 2022.01.03 [Spring] @RequestParam 와 @PathVariable (0) 2022.01.03 [Spring] querydsl - 집합 (0) 2022.01.03