빡코

[스프링 데이터 JPA] 페이징과 정렬 본문

카테고리 없음

[스프링 데이터 JPA] 페이징과 정렬

chris.djang 2023. 5. 11. 10:36

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#preface

 

Spring Data JPA - Reference Documentation

Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

예제

검색조건: 나이가 10

정렬조건: 이름으로내림차순

페이징조건: 번째페이지, 페이지당보여줄데이터는 3

//순순 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")
            .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 페이징과 정렬 
페이징과 정렬 파라미터
-org.springframework.data.domain.Sort: 정렬기능 
-org.springframework.data.domain.Pageable: 페이징기능 (내부에 Sort포함) 

특별한 반환타입 
-org.springframework.data.domain.Page: 추가 count 쿼리 결과를 포함하는 페이징 
-org.springframework.data.domain.Slice: 추가 count 쿼리 없이 다음페 이지만 확인 가능 
(내부적으로 limit + 1 조회) 
-List(자바컬렉션): 추가 count 쿼리 없이 결과만 반환
 
페이징과 정렬 사용 예제 
Page<Member>findByUsername(String name, Pageable pageable);//count 쿼리사용
//추가로 limit + 1을조회한다. 그래서다음페이지여부확인(최근모바일리스트생각해보면됨//
Slice<Member>findByUsername(String name, Pageable pageable);//count 쿼리사용안함
List<Member>findByUsername(String name, Pageable pageable);//count 쿼리사용안함
List<Member>findByUsername(String name, Sort sort);
 

Page 인터페이스 

package org.springframework.data.domain;

import java.util.Collections;
import java.util.function.Function;

 * @param <T>
 * @author Oliver Gierke

public interface Page<T> extends Slice<T> {

    //Returns the number of total pages.
    int getTotalPages();

    //Returns the total amount of elements.
    long getTotalElements();	
}

Page 사용 예제 실행 코드 

//페이징 테스트
@Test
public void paging() throws Exception {
    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));

    int age = 10;
    // 0~3개 가져오고, username 기준으로 내림차순 정렬!
    //두번째 파라미터로 받은P ageable은 인터페이스다.
    // 따라서 실제 사용할 때는 해당 인터페이스를 구현한 org.springframework.data.domain.PageRequest 객체를사용한다.
    // PageRequest 생성자의 첫번째 파라미터에는 현재 페이지를, 두번째파라미터에는 조회할 데이터 수를 입력한다.
    // 여기에 추가로 정렬정보도 파라미터로 사용할수있다. 참고로페이지는 0부터시작한다
    PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));
    Page<Member> page = memberRepository.findByAge(age, 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();//다음 페이지기 있는가?
}

count  쿼리를 다음과 같이 분리 가능 > 별도의 쿼리 실행 

//페이징
@Query(value = "select m from Member m left join m.team t",
        countQuery = "select(m.username) from Member m")
Page<Member> findByAge(int age, Pageable pageable);
//실행 쿼리 

select
    count(member0_.member_id) as col_0_0_ 
from
    member member0_

*Entity는 클라이언트 단에 절대 노출 시켜서는 안된다. 대신 DTO로 변환해서 반환해야 한다(API인 경우) 

//Entity 데이터
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));
Page<Member> page = memberRepository.findByAge(age, pageRequest);

//DTO로 변환
Page<MemberDto> toMap = page.map(member -> new MemberDto(member.getId(), member.getUsername(), null));

 

 

출처:

https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81-%EB%8D%B0%EC%9D%B4%ED%84%B0-JPA-%EC%8B%A4%EC%A0%84&unitId=28018&tab=curriculum