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 값을 변경해주면 페이지에 출력되는 값들을 바꿔줄 수 있다
'Spring' 카테고리의 다른 글
Java Spring_ @Mapping (0) | 2023.03.05 |
---|---|
Java Spring JPA (Cascade vs EntityManager.persist()) (0) | 2023.03.05 |
Spring Framework_ApplicationEventPublisher,@EventListener (0) | 2023.03.03 |
Spring을 이용해 이메일 보내는 방법 (0) | 2023.03.02 |
Regex (정규 표현식) #Java로 regex 이용하기 (0) | 2023.02.19 |