Spring

Spring Data JPA _ 페이징처리

검은고양이개발자 2023. 2. 22. 21:30
반응형

Spring Data JPA에서 페이징 처리하기


Spring Data JPA는 DB 쿼리를 작성하기 위해 간편하게 사용할 수 있는 API를 제공합니다.

이 중 페이징 처리를 도와주는 클래스와 메서드들을 사용하면 간단하게 페이징 기능을 구현할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

Page 클래스


Spring Data JPA에서 페이징 처리를 위해 사용하는 클래스는 Page 클래스입니다.

Page 클래스는 페이지 출력을 도와주는 클래스로 여러가지 메서드들이 존재합니다.

Page 클래스를 도와주는 메서드 중 PageRequest.of() 는  page와 size를 기본인자로 사용하며 추가적으로 정렬을 어떤 방식으로 할 것인지를 정할 수 있는 메서드입니다.

page와 size는 출력하고자 하는 페이지가 총 몇 페이지이며, 하나의 페이지에 몇 개의 요소를 출력할 것인지를 정하는 것입니다.

ex) page 4, size 5 (총 size 20, 보고싶은 페이지 2)  --> memberId 11~15에 관한 요소 출력

{
    "pageInfo": {
        "size": 5,
        "totalPages": 4,
        "page": 2,
        "totalElements": 20
    },
    "content": [
        {
            "memberId": 15,
            "email": "hgd15@gmail.com",
            "name": "홍길동15",
            "phone": "010-1515-1515"
        },
        {
            "memberId": 14,
            "email": "hgd14@gmail.com",
            "name": "홍길동14",
            "phone": "010-1414-1414"
        },
        {
            "memberId": 13,
            "email": "hgd13@gmail.com",
            "name": "홍길동13",
            "phone": "010-1313-1313"
        },
        {
            "memberId": 12,
            "email": "hgd12@gmail.com",
            "name": "홍길동12",
            "phone": "010-1212-1212"
        },
        {
            "memberId": 11,
            "email": "hgd11@gmail.com",
            "name": "홍길동11",
            "phone": "010-1111-1111"
        }
    ]
}

 

 

 

 

 

 

 

 

 

 

 

PagingAndSortingRepository 인터페이스


이제 이 Page를 이용하여 페이지 기능을 추가한 레포지터리를 만들어보겠습니다.

Spring Data JPA에서는 PagingAndSortingRepository 인터페이스를 상속시켜서 이용할 수 있습니다.(code 1)

이를 상속시킴으로 기본적인 Page 클래스를 이용할 수 있고 여러가지 메서드들도 이용할 수 있습니다.

그 중 findAll() 메서드는 Pageable이라는 타입을 받아들여서 Page 클래스로 반환시켜줍니다.(code 2)

 

public interface MemberRepository extends PagingAndSortingRepository<Member, Long> {
    Optional<Member> findByEmail(String email);
//    Page<Member> findAll(Pageable pageable);
}

<code 1> PagingAndSortingRepository 인터페이스를 상속시킴으로써 여러가지 메서드를 사용할 수 있다

ex) findAll()

 

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

   /**
    * Returns all entities sorted by the given options.
    *
    * @param sort the {@link Sort} specification to sort the results by, can be {@link Sort#unsorted()}, must not be
    *          {@literal null}.
    * @return all entities sorted by the given options
    */
   Iterable<T> findAll(Sort sort);

   /**
    * Returns a {@link Page} of entities meeting the paging restriction provided in the {@link Pageable} object.
    *
    * @param pageable the pageable to request a paged result, can be {@link Pageable#unpaged()}, must not be
    *          {@literal null}.
    * @return a page of entities
    */
   Page<T> findAll(Pageable pageable);
}

<code 2>  findAll을 찾아보면 Pageable 타입을 인자로 받고, Page 타입을 반환하는 것을 알 수 있다.

 

 

 

 

 

 

 

 

 

 

 

Page<T> 적용하기


Page<T>는 PageRequest.of(page, size, ...) 메서드를 통해 한 페이지에 얼마만큼의 요소가 출력 되게 할 것인지를 정할 수 있고, 페이지들 하나하나를 모아놓은 것이 Page<T>이다.

public Page<Member> findMembers(int page, int size) {
    
    return memberRepository.findAll(PageRequest.of(page, size, Sort.by("memberId").descending()));
}

 

 

 

 

Page 클래스는 getContent() 메서드를 통해 클래스 안의 요소들을 리스트화 시킬 수 있다.

 

 

 

 

따라서 이를 이용하여 요소들을 리스트화시켜줄 수 있습니다.

 

Page<Member> pageMembers = memberService.findMembers(page-1,size);
List<Member> members = pageMembers.getContent();
List<MemberResponseDto> response = mapper.membersToMemberResponseDtos(members);

Map<String, Object> pageInfo = new HashMap<>();
        pageInfo.put("page", page);
        pageInfo.put("size", size);
        pageInfo.put("totalElements", pageMembers.getTotalElements());
        pageInfo.put("totalPages", pageMembers.getTotalPages());

        return new ResponseEntity<>(
                new PageResponseDto<>(pageInfo, response),HttpStatus.OK);
    }

 

 

마지막으로 리스트화 된 데이터를 매핑을 통해 MemberResponseDto를 만든  뒤

 

ublic class PageResponseDto<T> {

    private Map<String, Object> pageInfo;
    private List<T> content;


    public PageResponseDto(Map<String, Object> pageInfo,List<T> content) {
        this.content = content;
        this.pageInfo = pageInfo;
    }
}

 

PageResponseDto 필드값으로 넣어주어 리턴해주면 페이지에 대한 정보까지 포함한 페이징처리를 완료할 수 있다!

 

# Params의 KEY, VALUE 값을 변경해주면 페이지에 출력되는 값들을 바꿔줄 수 있다

반응형