2 분 소요

인프런* 실전! Querydsl 강의 내용 정리

정렬

간단하게 예제를 풀어 보자.

  • 회원 정렬 순서
    1. 회원 나이 내림 차순 (desc)
    2. 회원 이름 올림 차순 (asc)
    3. 단 2에서 회원 이름이 없으면 마지막에 출력(nulls last)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test  
public void sort() throws Exception {  
    //given  
    em.persist(new Member(null, 100));  
    em.persist(new Member("member5", 100));  
    em.persist(new Member("member6", 100));  
  
    //when  
    List<Member> result = queryFactory  
            .selectFrom(member)  
            .where(member.age.eq(100))  
            .orderBy(member.age.desc(), member.username.asc().nullsLast())  
            .fetch();  
    Member member5 = result.get(0);  
    Member member6 = result.get(1);  
    Member memberNull = result.get(2);  
  
    //then  
    assertThat(member5.getUsername()).isEqualTo("member5");  
    assertThat(member6.getUsername()).isEqualTo("member6");  
    assertThat(memberNull.getUsername()).isNull();  
}
1
2
3
4
5
List<Member> result = queryFactory  
            .selectFrom(member)  
            .where(member.age.eq(100))  
            .orderBy(member.age.desc(), member.username.asc().nullsLast())  
            .fetch();  

다음과 같이 작성 했다.

일단 where절은 before에 데이터가 몇 개 있어서 제외 시키기 위한 것.

orderBy에선 처음에 member.age.desc()로 회원 나이 내림 차순 (desc)

그 후 member.username.asc().nullsLast() 일전에 배운 and 는 , 만 사용하면 되는 걸 이용해서 다음과 같이 작성. 이름을 오름차순, 그다음 nullsLast()로 null은 맨 마지막으로 정렬

이렇게 작성했다.

1
2
3
4
5
6
7
8
9
10
11
12
select
        m1_0.member_id,
        m1_0.age,
        m1_0.team_id,
        m1_0.username 
    from
        member m1_0 
    where
        m1_0.age=? 
    order by
        m1_0.age desc,
        m1_0.username asc nulls last

쿼리는 다음과 같이 나갔다.

페이징

다음과 같이 간단하게 가져올 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test  
public void paging() throws Exception {  
    //given  
    //when    
    List<Member> result = queryFactory  
            .selectFrom(member)  
            .orderBy(member.username.desc())  
            .offset(0)  
            .limit(2)  
            .fetch();  
    //then  
    assertThat(result.size()).isEqualTo(2);  
}

offset은 0 부터 시작이다.

이번엔 권장하지 않지만 fetchResults()로 결과를 받아서 페이징 해 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test  
public void paging2() throws Exception {  
    //given  
    //when    
    QueryResults<Member> queryResults = queryFactory  
            .selectFrom(member)  
            .orderBy(member.username.desc())  
            .offset(1)  
            .limit(2)  
            .fetchResults();  
    //then  
    assertThat(queryResults.getTotal()).isEqualTo(4);  
    assertThat(queryResults.getLimit()).isEqualTo(2);  
    assertThat(queryResults.getOffset()).isEqualTo(1);  
    assertThat(queryResults.getResults().size()).isEqualTo(2);  
}

기본 문법 1에서 말했지만, getTotal() 절대 믿으면 안된다. count 쿼리는 분리하자.

집합

기본 데이터

1
2
3
4
5
6
Team teamA = new Team("teamA");  
Team teamB = new Team("teamB");  
Member member1 = new Member("member1", 10, teamA);  
Member member2 = new Member("member2", 20, teamA);  
Member member3 = new Member("member3", 30, teamB);  
Member member4 = new Member("member4", 40, teamB);
  1. 다양한 연산
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    @Test  
    public void aggregation() throws Exception {  
     //given  
     List<Tuple> result = queryFactory  
             .select(  
                     member.count(),  
                     member.age.sum(),  
                     member.age.avg(),  
                     member.age.max(),  
                     member.age.min()  
             )  
             .from(member)  
             .fetch();  
     //when  
     Tuple tuple = result.get(0);  
     //then  
     assertThat(tuple.get(member.count())).isEqualTo(4);  
     assertThat(tuple.get(member.age.sum())).isEqualTo(100);  
     assertThat(tuple.get(member.age.avg())).isEqualTo(25);  
     assertThat(tuple.get(member.age.max())).isEqualTo(40);  
     assertThat(tuple.get(member.age.min())).isEqualTo(10);  
    }
    

    다음과 같은 쿼리도 가능하다. 멤버의 수, 나이 평균, 나이 전체 합 등등. 그런데 이때 리턴이 Tuple이다.

이를 주의해서 검증 때 tuple.get으로 검증한다.

나중에는 DTO로 값을 뽑을 것이기 때문에, 일단 알아두자.

1
2
3
4
5
6
7
8
select
        count(m1_0.member_id),
        sum(m1_0.age),
        avg(cast(m1_0.age as float(53))),
        max(m1_0.age),
        min(m1_0.age) 
    from
        member m1_0

쿼리는 다음과 같이 나온다.

  1. group by 당연히 SQL에서 group by 도 가능 하다.

팀 이름과 각 팀의 평균 연령을 구하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test  
public void group() throws Exception {  
    //given  
    List<Tuple> result = queryFactory  
            .select(team.name, member.age.avg())  
            .from(member)  
            .join(member.team, team)  
            .groupBy(team.name)  
            .fetch();  
    //when  
    Tuple teamA = result.get(0);  
    Tuple teamB = result.get(1);  
    //then  
    assertThat(teamA.get(team.name)).isEqualTo("teamA");  
    assertThat(teamA.get(member.age.avg())).isEqualTo(15);  
  
    assertThat(teamB.get(team.name)).isEqualTo("teamB");  
    assertThat(teamB.get(member.age.avg())).isEqualTo(35);  
}

여기서 join이 먼저 나오는데 일단 이렇게 쓴다는 것만 알아 두고 다음에 자세히 알아 보자.

.groupBy(team.name) 팀의 이름으로 groupBy를 했다.

1
2
3
4
5
6
7
8
9
10
select
        t1_0.name,
        avg(cast(m1_0.age as float(53))) 
    from
        member m1_0 
    join
        team t1_0 
            on t1_0.team_id=m1_0.team_id 
    group by
        t1_0.name

쿼리는 다음과 같이 나간다.

태그: ,

카테고리:

업데이트:

댓글남기기