웹 사이트를 이용하여 게시판을 둘러볼 때, 게시글 목록 하단에 게시글을 일정 수로 나누어 페이지화 시켜놓은것을 볼 수 있는데 이를 pagination(페이지네이션)이라고 합니다.
구현
- pagination을 구현하기 위해서는 현재 페이지번호,각 페이지별 보여질 내용의 수, 페이지에 들어갈 컨텐츠, 전체 페이지 수, 전체 데이터의 수가 필요합니다.
- 이 데이터들을 얻으려면 최소 2번의 API요청(데이터 요청,데이터 카운트 콜)을 통하여 데이터를 가져와야 합니다.
- 2번의 요청이 싫다고 한다면, 한번의 요청만으로 모든 데이터를 가져와야 하는데 이 경우에는 데이터가 매우 많을 경우 성능에 문제가 생길 수 있습니다.
- Spring 프레임워크에서는 이러한 고민을 해결 할 수 있는 방법중 하나가
<Spring-Data-JPA>
라이브러리의 <Page>
,<Pageable>
를 이용하는 것입니다.
JPA(Java Persistence API)
- 자바 ORM 기술에 대한 표준 명세로 JAVA에서 제공하는 API를 의미합니다.
- 간단히 말하면 자바에서 객체를 DB에 저장/로드 할 때 객체와 데이터베이스 사이에서 매핑을 도와주는 라이브러리를 의미합니다.
Spring Data JPA의 제공 메서드
Pageable
- Pageable은 Spring JPA에서 DB쿼리에 쉽고 유연하게 limit쿼리를 사용할 수 있게 해줍니다.
- 특히 JPA를 사용할 때, 자동으로 Pageable 타입의 변수를 넘겨주면 JPA가 DB에 접근하여 데이터를 가져올 때 자동으로 limit조건을 붙여서 데이터를 가져옵니다.
@PageableDefault
- Spring의 Controller의 메서드 파라미터에 해당 어노테이션이 선언 된 Pageable 타입 파라미터를 선언하게 되면, API 요청시 Pageable 객체에 대한 파라미터를 넘겨주지 않아도 자동으로 기본값을 가진 Pageable 타입 파라미터를 제공해줍니다.
- 이 어노테이션을 사용하지 않는다면
<HandlerMethodArgumentResolver>
같은 인터페이스를 구현한 클래스를 만들어 조건에 맞게 매핑을 해주어야 합니다.
Pageable 예제
public List<User> findByName(String name) {
return jpaUserRepository.findByName(name);
}
public List<User> findByName(String name) {
Pageable pageable = PageRequest.of(0,3);
return jpaUserRepository.findByName(name,pageable);
}
<Pageable>
는 <springframework.data.domain.Pageable>
을 사용합니다.
- PageRequest.of(int page,int size, sort, properties)를 통하여 PageRequest를 생성해 줍니다.
-page : 요청하는 페이지 번호
-size : 한 페이지 당 조회할 크기 (기본값:20)
-sort : Sorting설정 (기본값: 오름차순)
Page
- Pageable을 파라미터로하여 가져온 결과물은
Page<SomeObject>
형태로 반환 되며, Page를 사용한다면 대부분 다수의 row를 가져오기 때문에 Page<List<SomeObject>>
의 형태로 반환을 합니다.
- 이 페이지 객체에는 Pagination을 구현할 때 사용하면 좋은 메서드가 있습니다.
getTotalElements()
- 쿼리 결과물의 전체 데이터 개수입니다.
- 즉 Pageable에 의해
<limit>
키워드가 조건으로 들어가지 않는 쿼리 결과의 수 인데, 주의해야 할점은 쿼리 결과의 개수만 가져옵니다. 전체 데이터를 가져오지는 않습니다.
- 이 메서드는 게시판 기능 사용자에게 전체 데이터 개수를 알려줄 때 사용하면 좋습니다.
getTotalPages()
- 쿼리를 통해 가져온 요소들을 size크기에 맞춰 페이징하였을 떄 나오는 총 페이지의 개수입니다.
- 이를 활용하여 쉽게 페이지 버튼의 생성이 가능합니다.
getSize()
- 쿼리를 수행한 전체 데이터에 대해 일정 수 만큼 나눠 페이지를 구성하는데, 이 일정 수의 크기입니다.
getNumber()
getNumberOfElements()
- 페이지에 존재하는 요소의 개수입니다. 최대 size의 수만큼 나올 수 있습니다.