Querydsl에서 서브쿼리는 JPAExpressions를 이용한다 

서브쿼리에 사용하는 QType은 별도로 지정한 후 사용해야한다 

1. 나이가 가장 많은 회원 조회하기: max()함수 이용 

@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);
}

2. 나이가 평균 나이 이상인 회원: goe(이상) 사용

@Test
public void subQueryGoe() throws Exception {

    QMember memberSub = new QMember("memberSub");
    
    List<Member> result = queryFactory
            .selectFrom(member)
            .where(member.age.goe(
                    JPAExpressions
                            .select(memberSub.age.avg())
                            .from(memberSub)
)) 
.fetch();
      
      ssertThat(result).extracting("age")
              .containsExactly(30,40);
}

3. 서브쿼리 여러 건을 처리하기 위해 In을 사용한다 

.where(member.age.in(
                      JPAExpressions
                              .select(memberSub.age)
                              .from(memberSub)
                              .where(memberSub.age.gt(10))

4. 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)));
}

 

JPA JPQL에서 from절에서의 서브쿼리를 지원하지 않으므로 Querydsl도 지원하지 않는다. 

 

그래서 from 절의 서브쿼리 해결방안으로는 

 

1. 서브쿼리를 join으로 변경한다.(가능한 상황도 있고, 불가능한 상황도 있다)

2. 애플리케이션에서 쿼리를 2번 분리해서 실행한다. SQL anti pattern 책 소개하심

3. nativeSQL을 사용한다 

+ Recent posts