- 일반정렬
desc(),asc()- null 데이터 순서 부여
nullsLast(),nullsFirst()
- 회원 정렬 순서
- 회원 나이 내림차순(desc)
- 회원 이름 올림차순(asc)
- 단, 2에서 회원 이름이 없으면 마지막에 출력(nulls last)
/**
* 정렬
* 회원 정렬 순서
* 1. 회원 나이 내림차순(desc)
* 2. 회원 이름 올림차순(asc)
* 단, 2에서 회원 이름이 없으면 마지막에 출력(nulls last)
*/
@Test
public void sort() {
// 기존 4명의 회원에 3명의 회원 추가
em.persist(new Member(null, 100));
em.persist(new Member("member5", 100));
em.persist(new Member("member6", 100));
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.eq(100)) // 회원 중 나이가 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);
assertThat(member5.getUsername()).isEqualTo("member5");
assertThat(member6.getUsername()).isEqualTo("member6");
assertThat(memberNull.getUsername()).isNull();
}
.orderBy(member.age.desc(), member.username.asc().nullsLast())
fetch()사용!
/**
* 페이징
*/
@Test
public void paging1() {
List<Member> result = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1) // 앞에 몇개 스킵할건지, 0부터 시작
.limit(2) // 몇개의 데이터 가져올건지
.fetch();
assertThat(result.size()).isEqualTo(2);
}
fetchResults()사용!
/**
* 페이징 - 전체 조회 수 필요
*/
@Test
public void paging2() {
// fetchResults : 쿼리 2번(count query, contents가져오는 query)
QueryResults<Member> queryResults = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1) // 앞에 몇개 스킵할건지, 0부터 시작
.limit(2) // 몇개의 데이터 가져올건지, 최대 2건 조회
.fetchResults();
assertThat(queryResults.getTotal()).isEqualTo(4);
assertThat(queryResults.getLimit()).isEqualTo(2);
assertThat(queryResults.getOffset()).isEqualTo(1);
assertThat(queryResults.getResults().size()).isEqualTo(2); // 컨텐츠
}
getTotal, getLimit, getOffset, getResults 등의 함수 사용이 가능!
✅ 참고
실무에서는 페이징 쿼리 작성시, 데이터 조회하는 쿼리는 여러 테이블 조인해야하지만, count 쿼리는 조인이 필요없는 경우도 있다.
이런 경우 자동화된 count 쿼리는 원본 쿼리와 같이 모두 조인해버려서 성능이 안나올 수 있다.
따라서 count 전용 쿼리를 별도로 작성해 성능 최적화를 한다.
count,sum,avg,max,min
/**
* 집합
* JPQL이 제공하는 집합함수 모두 제공
*
* == JPQL ==
* select
* COUNT(m), //회원수
* SUM(m.age), //나이 합
* AVG(m.age), //평균 나이
* MAX(m.age), //최대 나이
* MIN(m.age) //최소 나이
* from Member m
*/
@Test
public void aggregation() {
List<Tuple> result = queryFactory // 결과 타입 : querydsl이 제공하는 Tuple
.select(
member.count(),
member.age.sum(),
member.age.avg(),
member.age.max(),
member.age.min()
)
.from(member)
.fetch();
Tuple tuple = result.get(0); // tuple 리스트에서 tuple 꺼내오고
assertThat(tuple.get(member.count())).isEqualTo(4); // tuple.get(위에서 select 다음에 썼던 거 똑같이 작성)
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);
}
팀의 이름과 각 팀의 평균 연령을 구해라
groupBy(team.name)
/**
* group by
*
* 팀의 이름과 각 팀의 평균 연령을 구해라
*/
@Test
public void group() {
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);
assertThat(teamA.get(team.name)).isEqualTo("teamA"); // tuple.get(select절에 썼던 거)
assertThat(teamA.get(member.age.avg())).isEqualTo(15);
assertThat(teamB.get(team.name)).isEqualTo("teamB");
assertThat(teamB.get(member.age.avg())).isEqualTo(35);
}
그룹화된 결과 제한
…
.groupBy(item.price)
.having(item.price.gt(1000))
…
package com.querydsl.core이 제공하는 Tuple의 get 함수이다.
