Published 2022. 7. 25. 13:31

com.querydsl.jpa.JPAExpressions 사용

 

서브 쿼리 eq 사용

/**
 * 나이가 가장 많은 회원 조회
 */@Test
public void subQuery() throws Exception {
 QMember memberSub = new QMember("memberSub");
 List<Member> result = queryFactory
 .selectFrom(member)
 .where(member.age.eq(
 JPAExpressions
 .select(memberSub.age.max())
 .from(memberSub)
 ))
 .fetch();
 
 assertThat(result).extracting("age")
 .containsExactly(40);
}

 

서브 쿼리 goe 사용

@Test
    public void subQueryGoe() {

        QMember memberSub = new QMember("memberSub");

        List<Member> result = queryFactory
                .selectFrom(member)
                .where(member.age.goe(
                        JPAExpressions.select(memberSub.age.avg())
                                .from(memberSub)
                ))
                .fetch();

        assertThat(result).extracting("age").containsExactly(30, 40);
    }

 

 

서브쿼리 여러 건 처리 in 사용

@Test
    public void subQueryIn() {

        QMember memberSub = new QMember("memberSub");

        List<Member> result = queryFactory
                .selectFrom(member)
                .where(member.age.in(
                        JPAExpressions.select(memberSub.age)
                                .from(memberSub)
                                .where(memberSub.age.gt(10))
                ))
                .fetch();

        assertThat(result).extracting("age").containsExactly(20, 30, 40);
    }

 

 

 

 

select 절에 subquery

List<Tuple> fetch = queryFactory
 .select(member.username,
 JPAExpressions
 .select(memberSub.age.avg())
 .from(memberSub)
 ).from(member)
 .fetch();
for (Tuple tuple : fetch) {
 System.out.println("username = " + tuple.get(member.username)); System.out.println("age = " +
tuple.get(JPAExpressions.select(memberSub.age.avg())
 .from(memberSub)));
}

 

 

 

static import 활용

import static com.querydsl.jpa.JPAExpressions.select;
List<Member> result = queryFactory
 .selectFrom(member)
 .where(member.age.eq(
 select(memberSub.age.max())
 .from(memberSub)
 ))
 .fetch();

from 절의 서브쿼리 한계

JPA JPQL 서브쿼리의 한계점으로 from 절의 서브쿼리(인라인 뷰)는 지원하지 않는다. 당연히 Querydsl도 지원하지 않는다. 하이버네이트 구현체를 사용하면 select 절의 서브쿼리는 지원한다. Querydsl도 하이버네이트 구현체를 사용하면 select 절의 서브쿼리를 지원한다.

 

 

from 절의 서브쿼리 해결방안

1. 서브쿼리를 join으로 변경한다. (가능한 상황도 있고, 불가능한 상황도 있다.)
2. 애플리케이션에서 쿼리를 2번 분리해서 실행한다.
3. nativeSQL을 사용한다.

 

 

 

 

출처 : 김영한 JPA 스프링 데이터 강의

'Querydsl' 카테고리의 다른 글

상수, 문자 더하기  (0) 2022.07.25
Case 문  (0) 2022.07.25
조인 - 페치 조인  (0) 2022.07.25
조인 - on절  (0) 2022.07.25
조인 - 기본 조인  (0) 2022.07.24
복사했습니다!