서브쿼리는 기본적으로 다음의 패키지를 사용한다.
com.querydsl.jpa.JPAExpressions
실제로 사용해보자.
/**
* 나이가 가장 많은 회원 조회
*/
@Test
public void subQuery() {
//서브쿼리는 별칭이 겹치면 안된다.
QMember memberSub = new QMember("memberSub");
List<Member> fetch = queryFactory
.selectFrom(member)
.where(member.age.eq(
JPAExpressions
.select(memberSub.age.max())
.from(memberSub)
))
.fetch();
assertThat(fetch).extracting("age").containsExactly(40);
}
여기서 중요한건 만약 같은 테이블 대상으로 서브쿼리를 날릴거라면 서브쿼리내 별칭은 메인쿼리의 별칭과 동일해서는 안된다는 것이다.
생성된 jpql을 보면 위와 같다.
@Test
public void subQueryIn() {
//서브쿼리는 별칭이 겹치면 안된다.
QMember memberSub = new QMember("memberSub");
List<Member> fetch = queryFactory
.selectFrom(member)
.where(member.age.in(
JPAExpressions
.select(memberSub.age)
.from(memberSub)
.where(memberSub.age.gt(10))
))
.fetch();
assertThat(fetch).extracting("age").containsExactly(20, 30, 40);
}
생성된 jpql의 모습
서브쿼리는 select절에서도 가능하다.
@Test
public void selectSubQuery() {
QMember memberSub = new QMember("memberSub");
List<Tuple> fetch = queryFactory.select(member.username,
JPAExpressions
.select(memberSub.age.avg())
.from(memberSub))
.from(member)
.fetch();
for(Tuple tuple : fetch) {
System.out.println("tuple = " + tuple);
}
}
💡 참고로
JPAExpressions
은 스태틱 임포트가 가능하다.