기본 조인
List<Member> result1 = queryFactory
.selectFrom(member)
.join(member.team, team)
.where(team.name.eq("teamA"))
.fetch();
세타 조인
theta join을 이용해서 연관관계가 없는 필드도 조인을 할 수 있다
sql을 보면 cross가 있는데, "카테시안 곱"을 통하여 모든 엔티티를 조인한 다음, where 조건에 맞는 스키마를 찾는다
그래서 팀 2개, 멤버가 7개 이므로 카테시안 곱의 결과는 총 14개임을 알 수 있다
member, team 테이블
카테시안 곱 결과
결과
on 절
ON 절을 사용하여 "조인 대상 필터링"과 "연관관계가 없는 필드로 외부 조인"할 수 있다
조인 대상 필터링
일반적으로 JPQL에서 조인을 할 시, member와 team의 id를 통해 조인을 하지만 ON을 이용하면 조인 대상을 필터링할 수 있게 된다
그런데 inner join을 사용하여 on절을 사용할 경우는 where 절에서 필터링한 것과 동일하기 때문에, 만약 inner join이면 그냥 where을 쓰도록 하자~
List<Tuple> result1 = queryFactory
.select(member, team)
.from(member)
.leftJoin(member.team, team).on(team.name.eq("teamA"))
.fetch();
연관관계가 없는 필드로 외부 조인
List<Tuple> result = queryFactory
.select(member, team)
.from(member)
.leftJoin(team).on(member.username.eq(team.name))
.fetch();
sql을 보면 ON 절의 조건만으로 조인하는 것을 알 수 있다
List<Tuple> result = queryFactory
.select(member, team)
.from(member)
.leftJoin(member.team, team).on(member.username.eq(team.name))
.fetch();
sql을 보면 ON절의 조건 뿐만 아니라 외래키를 사용하여 조인하는 것을 볼 수 있다
둘의 차이는 뭘까?
코드를 자세히 보면 leftJoin 메서드에 "member.team"의 유무이다
만약에 member.team, team일 경우에는 id를 가지고 조인을 하기 때문에 ON절만을 이용하여 조인할 경우에는 member.team을 빼줘야한다는 것을 알 수 있다
서브 쿼리
QMember qMember = new QMember("selectQuery");
List<Member> result2 = queryFactory
.selectFrom(member)
.where(member.age.eq(
JPAExpressions.select(qMember.age.max())
.from(qMember)))
.fetch();
서브 쿼리는 "JPAExpressions"를 이용하여 사용할 수 있다(물론 static import 가능)
하지만 여기서 중요한 점은 QMember에 대한 객체를 하나 더 생성해줘야한다
왜냐하면 SQL에서도 서브 쿼리와 본 쿼리의 테이블에 대한 별칭이 달라야하는 것처럼,
우리가 static import한 QMember와 다르게 해야하기 때문에 다른 별칭을 가진 QMember 객체를 생성해줘야한다
REFERENCES
'Spring 강의 > QueryDSL' 카테고리의 다른 글
순수 JPA Repo + Querydsl, 동적 쿼리 (0) | 2022.05.14 |
---|---|
수정, 삭제 벌크 연산 (0) | 2022.05.13 |
프로젝션과 결과 반환, 동적 쿼리 (0) | 2022.05.12 |
JPQL & Querydsl , Querydsl 검색 조건, 결과(fetch), 정렬, 페이징, 집합 (0) | 2022.04.29 |