-
Querydsl - 정렬과 페이징, 집합JPA/Querydsl 2023. 8. 12. 23:28
정렬
/** * 회원 정렬 순서 * 1. 회원 나이 내림차순(desc) * 2. 회원 이름 올림차순(asc) * 만약, 회원 이름이 없으면 마지막에 출력(nulls last) */ @Test public void sort() { 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)) .orderBy(member.age.desc(), member.username.asc().nullsLast()) // nullsLast는 해당 데이터가 null이면 마지막으로 정렬 (nullsFirst는 맨 앞으로) .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(); }
기본 데이터들의 나이는 적기 때문에 테스트를 위해 새로 persist한 데이터들이 조건에 의해서 먼저 나오게 될 것이다. 나이가 많은 순으로 정렬하고 이름 순으로 올림차순 했으니 member5가 첫 번째, member6가 두 번째이다. memberNull은 이름이 없다. 하지만 member.username.asc().nullsLast라는 문장에 의해 나이로 정렬로 한 뒤, 이름의 정렬을 할 때 맨 뒤로 가기때문에 나이가 같은 member5, member6 바로 아래에서 조회가 되는 것이다.
desc(), asc()로 기본 정렬
nullsLast(), nullsFirst()로 null 값 정렬
페이징
@Test public void paging1() { List<Member> result = queryFactory .selectFrom(member) .orderBy(member.username.desc()) .offset(0) .limit(2) .fetch(); assertThat(result.size()).isEqualTo(2); } @Test public void paging2() { // 전체 조회수까지 필요할 때 QueryResults<Member> result = queryFactory .selectFrom(member) .orderBy(member.username.desc()) .offset(0) .limit(2) .fetchResults(); assertThat(result.getTotal()).isEqualTo(4); assertThat(result.getLimit()).isEqualTo(2); assertThat(result.getOffset()).isEqualTo(0); assertThat(result.getResults().size()).isEqualTo(2); }
전체 조회 개수가 필요하면 paging2()처럼 fetchResults()로 결과를 조회하면 된다.
하지만 성능 상 전체 조회 개수를 분리해야 한다면 paging1()처럼 fetch()를 사용하면 된다.
집합
@Test public void aggregation() { 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); 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); }
count(), sum() 등의 집합을 사용하는데 JPQL과 방법이 매우 유사해서 별도의 설명 없이 이해할 수 있을 것이다.
@Test public void group() throws Exception { 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"); assertThat(teamA.get(member.age.avg())).isEqualTo(15); assertThat(teamB.get(team.name)).isEqualTo("teamB"); assertThat(teamB.get(member.age.avg())).isEqualTo(35); }
groupBy를 team.name으로 해오는 것이다. 반환 타입이 Tuple의 리스트로 반환되는 특징이 있다.
Querydsl을 공부하고 있는데 기본적으로 JPQL과 많이 겹치는데 JPQL을 간편하게 해주는 것이라 이해하기 어렵진 않지만 JPQL을 더 확실하게 공부하고 Querydsl도 실수 없이 사용할 수 있도록 익숙해져야 한다는 생각이 들었다.
'JPA > Querydsl' 카테고리의 다른 글
Querydsl - 서브 쿼리 (0) 2023.08.13 Querydsl - 조인 (0) 2023.08.13 Querydsl - 검색(select)과 결과 조회 (0) 2023.08.12 Querydls과 JPQL의 차이 (0) 2023.08.12 Querydls의 기본 설정 (0) 2023.08.12