QueryDSL 기본 문법 - 2

집합

/**
 * JPQL
 * select
 *    COUNT(m),   //회원수
 *    SUM(m.age), //나이 합
 *    AVG(m.age), //평균 나이
 *    MAX(m.age), //최대 나이
 *    MIN(m.age)  //최소 나이
 * from Member m
 */
@Test
void aggregation() {
    List<Tuple> result = query
                        .select(member.count(),
                                member.age.sum(),
                                member.age.avg(),
                                member.age.max(),
                                member.age.min())
                        .from(member)
                        .fetch();
    Tuple tuple = result.get(0);
    assertThat(tuple.get(member.count())).isEqualTo(4);
    assertThat(tuple.get(member.age.sum())).isEqualTo(10 + 20 + 30 + 40);
    assertThat(tuple.get(member.age.avg())).isEqualTo((double) (10 + 20 + 30 + 40) / 4);
    assertThat(tuple.get(member.age.max())).isEqualTo(40);
    assertThat(tuple.get(member.age.min())).isEqualTo(10);
}

JPQL이 제공하는 모든 집합 함수를 제공한다. tuple이라는 것이 반환된다.

Group By

팀의 이름과 각 팀의 평균 연령을 구하는 쿼리가 실행된다.

그룹화된 결과를 제한하려면 having을 쓸 수 있다.

가격이 1,000원 이상인 상품들만 그룹화한다.

조인

기본 조인

조인에 기본 문법은 첫 번째 파라미터에 조인 대상을 지정하고 두 번째 파라미터에 별칭(alias)으로 사용할 Q 타입을 지정한다.

teamA에 소속된 모든 회원을 찾는 쿼리가 실행된다. join(), innerJoin(), leftJoin(), rightJoin()이 있다.

세타 조인

회원의 이름과 팀의 이름이 같은 회원을 조회하는 쿼리가 실행된다. from()절에 연관관계가 없는 필드로 여러 엔티티를 선택하면 세타 조인(crossJoin)이 실행된다. 외부 조인이 불가능하다.

조인 - on절

  • 조인 대상 필터링

회원과 팀을 조인(leftJoin)하는데 팀 이름이 "teamA"인 팀만 조회한다. 회원은 모두 조회된다.(leftJoin이니까)

on절로 조인 대상을 필터링할 때 내부조인(inner join)을 사용하면 where절에서 필터링 하는 것과 기능이 동일하다. 조인 대상 필터링을 할 때 내부조인이면 익숙한 where절로 해결하고 외부조인이 필요한 경우에 on절을 쓰는 것이 좋다.

  • 연관관계 없는 엔티티 외부 조인

회원의 이름과 팀의 이름이 같이 대상을 외부 조인한다.

on을 사용해서 서로 관계가 없는 필드로 외부 조인을 할 수 있다.(내부 조인도 가능)

  • 일반 조인: leftJoin(member.team, team)

  • on조인 : from(member).leftJoin(team).on(...) 일반 조인과 다르게 엔티티 하나만 들어간다.

페치 조인

  • 페치 조인 미적용

  • 페치 조인 적용

join(), leftJoin()등 조인 기능 뒤에 fetchJoin()이라고 추가하면 된다.

Last updated