Querydsl - 기본 문법 - 2 정렬, 페이징, 집합
인프런* 실전! Querydsl 강의 내용 정리
정렬
간단하게 예제를 풀어 보자.
- 회원 정렬 순서
- 회원 나이 내림 차순 (desc)
- 회원 이름 올림 차순 (asc)
- 단 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 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
쿼리는 다음과 같이 나온다.
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
쿼리는 다음과 같이 나간다.
댓글남기기