-
Spring Data JPA - 페이징과 정렬Spring/Spring Data JPA 2022. 3. 20. 18:43728x90반응형
페이징과 정렬
- 순수 JPA 페이징과 정렬
- 스프링 데이터 JPA 페이징과 정렬
순수 JPA의 페이징과 정렬
public List<Member> findByPage(int age, int offset, int limit) { return em.createQuery("select m from Member m where m.age = :age order by m.username desc", Member.class) .setParameter("age", age) .setFirstResult(offset) .setMaxResults(limit) .getResultList(); } public long totalCount(int age) { return em.createQuery("select count(m) from Member m where m.age = :age", Long.class) .setParameter("age", age) .getSingleResult(); }
스프링 데이터 JPA의 페이징과 정렬
- 페이징과 정렬 파라미터
- Sort : 정렬 기능
- Pageable : 페이징 기능(내부에 Sort 포함), 구현체로 PageRequest 사용 - 특별한 반환 타입
- Page : count 쿼리 결과를 포함하는 페이징
- Slice : count 쿼리 없이 다음 페이지만 확인 가능(내부적으로 limit + 1 조회)
- List : count 쿼리 없이 결과만 반환 - 주의: Page는 1부터 시작이 아니라 0부터 시작이다.
Page<Member> findByUsername(String name, Pageable pageable); //count 쿼리 사용 Slice<Member> findByUsername(String name, Pageable pageable); //count 쿼리 사용 안함 List<Member> findByUsername(String name, Pageable pageable); //count 쿼리 사용 안함 List<Member> findByUsername(String name, Sort sort);
테스트 코드
@Test public void page() throws Exception { //given memberRepository.save(new Member("member1", 10)); memberRepository.save(new Member("member2", 10)); memberRepository.save(new Member("member3", 10)); memberRepository.save(new Member("member4", 10)); memberRepository.save(new Member("member5", 10)); //when PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Page<Member> page = memberRepository.findByAge(10, pageRequest); //then List<Member> content = page.getContent(); //조회된 데이터 assertThat(content.size()).isEqualTo(3); //조회된 데이터 수 assertThat(page.getTotalElements()).isEqualTo(5); //전체 데이터 수 assertThat(page.getNumber()).isEqualTo(0); //페이지 번호 assertThat(page.getTotalPages()).isEqualTo(2); //전체 페이지 번호 assertThat(page.isFirst()).isTrue(); //첫번째 항목인가? assertThat(page.hasNext()).isTrue(); //다음 페이지가 있는가? }
Page 인터페이스
public interface Page<T> extends Slice<T> { int getTotalPages(); //전체 페이지 수 long getTotalElements(); //전체 데이터 수 <U> Page<U> map(Function<? super T, ? extends U> converter); //변환기 }
Slice 인터페이스
public interface Slice<T> extends Streamable<T> { int getNumber(); //현재 페이지 int getSize(); //페이지 크기 int getNumberOfElements(); //현재 페이지에 나올 데이터 수 List<T> getContent(); //조회된 데이터 boolean hasContent(); //조회된 데이터 존재 여부 Sort getSort(); //정렬 정보 boolean isFirst(); //현재 페이지가 첫 페이지 인지 여부 boolean isLast(); //현재 페이지가 마지막 페이지 인지 여부 boolean hasNext(); //다음 페이지 여부 boolean hasPrevious(); //이전 페이지 여부 Pageable getPageable(); //페이지 요청 정보 Pageable nextPageable(); //다음 페이지 객체 Pageable previousPageable(); //이전 페이지 객체 <U> Slice<U> map(Function<? super T, ? extends U> converter); //변환기 }
count 쿼리
- count 쿼리 때문에 성능이 안 좋아질 수 있으므로 count 쿼리를 따로 작성할 수 있다.
- 카운트 쿼리 분리(이건 복잡한 sql에서 사용, 데이터는 left join, 카운트는 left join 안 해도 됨)
@Query(value = “select m from Member m”, countQuery = “select count(m.username) from Member m”) Page<Member> findMemberAllCountBy(Pageable pageable);
페이징을 유지하면서 Entity를 DTO로 변환하기
- Page의 map 메서드를 이용하여 DTO를 변환한 후 페이징을 유지하여 새로운 Page를 반환할 수 있다.
Page<Member> page = memberRepository.findByAge(10, pageRequest); Page<MemberDto> dtoPage = page.map(m -> new MemberDto());
728x90반응형'Spring > Spring Data JPA' 카테고리의 다른 글
Spring Data JPA - 엔티티의 생성, 변경한 사람과 시간을 추적(Auditing) (0) 2022.03.21 Spring Data JPA - 사용자 정의 리포지토리 구현 (0) 2022.03.21 Spring Data JPA - @EntityGraph (0) 2022.03.20 Spring Data JPA - 벌크성 수정 쿼리 (0) 2022.03.20 Spring Data JPA - 쿼리 메서드 사용과 @Query (1) 2022.03.19