Tools & Libraries/Querydsl

[Querydsl] Querydsl 기본문법 3 (집합 연산, 조인)

대기업 가고 싶은 공돌이 2024. 9. 3. 19:19

집합 연산

@Test
public void aggregation(){
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);

    List<Tuple> result = queryFactory.select(
                    member.count(),
                    member.age.sum(),
                    member.age.avg(),
                    member.age.max(),
                    member.age.min()
            ).from(member)
            .fetch();

    Tuple tuple = result.get(0);

    Assertions.assertThat(tuple.get(member.count())).isEqualTo(4);
    Assertions.assertThat(tuple.get(member.age.sum())).isEqualTo(100);

}

 

위와 같이 select 절에 집합 연산자를 집어넣어 연산을 수행할 수 있다.

 

select 절에 들어간 타입이 위와 같이 여러 개인 경우엔 tuple 자료형을 통해 값을 받아야한다.

 

tuple이란 여러가지 자료형을 한 번에 받을 수 있도록 설계된 자료형이다.

 

tuple에서 값을 꺼내는 방법은 위와 같이

tuple.get(member.count()) 로 select 절에 썼던 함수를 그대로 get 안에 넣어주면 된다.

 

실무에서는 tuple 말고 dto를 통해 직접 뽑아오는 방식을 사용한다고 한다. (뒤에서 배움)

 

group by 사용 방법

/**
 * 팀 이름과 각 팀의 평균 연령을 구해라
 */
@Test
public void group(){
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);

    List<Tuple> result = queryFactory.select(team.name, member.age.avg())
            .from(member)
            .join(member.team, team)
            .groupBy(team.name)
            .fetch();

    Tuple teamA = result.get(0);
    Tuple teamB = result.get(1);

    Assertions.assertThat(teamA.get(team.name)).isEqualTo("teamA");
    Assertions.assertThat(teamA.get(member.age.avg())).isEqualTo(15);
}

 

위와 같이 team.name으로 group by를 진행해서 select 를 할 수 있다.

 

조인

기본 조인

  • 첫 번째 파라미터에 조인 대상을 지정하고, 두 번째 파라미터에 별칭으로 사용할 Q type을 지정하면 된다.
join(조인 대상, 별칭으로 사용할 Q타입)

 

/**
 * 팀 A에 소속된 모든 회원을 찾아라.
 */
@Test
public void join(){
    JPAQueryFactory queryFactory = new JPAQueryFactory(em);

    List<Member> result = queryFactory.selectFrom(member)
            .join(member.team, team)
            .where(team.name.eq("teamA"))
            .fetch();

    Assertions.assertThat(result)
            .extracting("username")
            .containsExactly("member1", "member2");
}

 

다음과 같은 쿼리를 실행하면 

다음과 같이 inner join이 나가는 것을 볼 수 있다.

 

left join

List<Member> result = queryFactory.selectFrom(member)
        .leftJoin(member.team, team)
        .where(team.name.eq("teamA"))
        .fetch();

 

다음과 같이 join 부분만 바꿔주면 left, right 등등을 모두 사용할 수 있다.

 

세타 조인 (카타시안 곱)

queryFactory
.select(member)
.from(member, team)
.where(member.username.eq(team.name))
.fetch();

 

위와 같이 from 절에 다른 테이블(엔티티)를 나열만 해주면 알아서 카타시안 곱으로 반환한다.

 

참고: 김영한 실전! Querydsl