오봉이와 함께하는 개발 블로그
스프링 데이터 JPA - Web 확장 페이징과 정렬 본문
728x90
Web 확장 - 페이징과 정렬
스프링 데이터가 제공하는 페이징과 정렬 기능을 스프링 MVC에서 편리하게 사용할 수 있다.
페이징과 정렬 예제
@GetMapping("/members")
public Page<Member> list(Pageable pageable) {
Page<Member> page = memberRepository.findAll(pageable);
return page;
}
- 파라미터로 Pageable을 받을 수 있다.
- Pageable은 인터페이스다.
- 실제는 org.springframework.data.domain.PageRequest 객체 생성
{
.........................
{
"createdDate": "2022-09-14T01:54:54.034161",
"lastModifiedDate": "2022-09-14T01:54:54.034161",
"createdBy": "cbd93077-4360-4b66-975d-64e3acab775e",
"lastModifiedBy": "cbd93077-4360-4b66-975d-64e3acab775e",
"id": 20,
"username": "user19",
"age": 19,
"team": null
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"pageNumber": 0,
"pageSize": 20,
"offset": 0,
"paged": true,
"unpaged": false
},
"totalPages": 5,
"totalElements": 100,
"last": false,
"numberOfElements": 20,
"first": true,
"number": 0,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"size": 20,
"empty": false
}
요청 파라미터
- 예 : /members?page=0&size=3&sort=id,desc&sort=username,desc
- page : 현재 페이지, 0부터 시작한다.
- size : 한 페이지에 노출할 데이터 건수
- sort : 정렬 조건을 정의한다.
- 예 : 정렬 속성,정렬 속성...(ASC | DESC)
- 정렬 방향을 변경하고 싶으면 sort파라미터 추가 (asc 생략 가능)
{
"content": [
{
"createdDate": "2022-09-14T01:54:54.291475",
"lastModifiedDate": "2022-09-14T01:54:54.291475",
"createdBy": "6def164a-778b-4ae5-bf45-5c67914d2c8b",
"lastModifiedBy": "6def164a-778b-4ae5-bf45-5c67914d2c8b",
"id": 100,
"username": "user99",
"age": 99,
"team": null
},
{
"createdDate": "2022-09-14T01:54:54.288771",
"lastModifiedDate": "2022-09-14T01:54:54.288771",
"createdBy": "6975352b-9832-4445-9caf-89ea4a2c4b27",
"lastModifiedBy": "6975352b-9832-4445-9caf-89ea4a2c4b27",
"id": 99,
"username": "user98",
"age": 98,
"team": null
},
{
"createdDate": "2022-09-14T01:54:54.285728",
"lastModifiedDate": "2022-09-14T01:54:54.285728",
"createdBy": "da495521-9b0b-499f-9390-76c68d19eb08",
"lastModifiedBy": "da495521-9b0b-499f-9390-76c68d19eb08",
"id": 98,
"username": "user97",
"age": 97,
"team": null
}
],
"pageable": {
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"pageNumber": 0,
"pageSize": 3,
"offset": 0,
"paged": true,
"unpaged": false
},
"totalPages": 34,
"totalElements": 100,
"last": false,
"numberOfElements": 3,
"first": true,
"number": 0,
"sort": {
"sorted": true,
"unsorted": false,
"empty": false
},
"size": 3,
"empty": false
}
기본값
- 글로벌 설정 : 스프링 부트
spring.data.web.pageable.default-page-size=20 /# 기본 페이지 사이즈/
spring.data.web.pageable.max-page-size=2000 /# 최대 페이지 사이즈/
- 개별 설정
- @PageableDefault 어노테이션을 사용
@RequestMapping(value = "/members_page", method = RequestMethod.GET)
public String list(@PageableDefault(size = 12, sort = "username",
direction = Sort.Direction.DESC) Pageable pageable) {
// ...............
}
접두사
- 페이징 정보가 둘 이상이면 접두사로 구분
- @Qualifier 에 접두사명 추가 {접두사명}_xxx
- 예 : /members?member_page=0&order_page=1
Page 내용을 DTO로 변환하기
- 엔티티를 API로 노출하면 다양한 문제가 발생한다.
- 그래서 엔티티를 꼭 DTO로 변환해서 반환해야 한다.
- Page는 map()을 지원해서 내부 데이터를 다른 것으로 변경할 수 있다.
MemberDTO
@Data
public class MemberDto {
private Long id;
private String username;
public MemberDto(Long id, String username) {
this.id = id;
this.username = username;
}
}
Page.map()
사용
@GetMapping("/members")
public Page<MemberDto> list(Pageable pageable) {
Page<Member> page = memberRepository.findAll(pageable);
Page<MemberDto> memberDto = page.map(m -> new MemberDto(m.getId(), m.getUsername()));
return memberDto;
}
MemberDTO 최적화
DTO는 엔티티를 알고 있어도 괜찮기 때문에 아래와 같이 엔티티를 생성자 파라미터로 받을 수 있다.
@Data
public class MemberDto {
private Long id;
private String username;
public MemberDto(Member member) {
this.id = member.getId();
this.username = member.getUsername();
}
}
@GetMapping("/members")
public Page<MemberDto> list(Pageable pageable) {
Page<Member> page = memberRepository.findAll(pageable);
Page<MemberDto> memberDto = page.map(MemberDto::new);
return memberDto;
}
Page를 1부터 시작하기
스프링 데이터는 Page를 0부터 시작하는데, 만약 1부터 시작하려면?
- Pageable, Page를 파리미터와 응답 값으로 사용히지 않고, 직접 클래스를 만들어서 처리한다. 그리고 직접 PageRequest(Pageable 구현체)를 생성해서 리포지토리에 넘긴다. 물론 응답값도 Page 대신에 직접 만들어서 제공해야 한다.
@GetMapping("/members")
public MyPage<MemberDto> list() {
PageRequest request = PageRequest.of(1, 2); // page(시작 페이지), size(페이지 사이즈)
Page<MemberDto> memberDto = page.map(MemberDto::new);
MyPage<MemberDto> result = ..............
}
- spring.data.web.pageable.one-indexed-parameters를 true로 설정한다. 그런데 이 방법은 web에서 page파라미터를 -1 처리 할 뿐이다. 따라서 응답값인 Page에 모두 0 페이지 인덱스를 사용하는 한계가 있다.
application.properties
spring.data.web.pageable.one-indexed-parameters=true
one-indexed-parameters Page
1요청 (http://localhost:8080/members?page=1
)
{
"content": [
...
],
"pageable": {
"offset": 0,
"pageSize": 10,
"pageNumber": 0 //0 인덱스
},
"number": 0, //0 인덱스
"empty": false
}
위 결과와 같이 1로 요청해도 시작은 0을 기준으로 한다.
http://localhost:8080/members?page=0
으로 요청 했을 때는 기본적으로 1로 요청한것과 동일하게 요청된다.
인프런 김영한 지식공유자님 강의 : 실전! 스프링 데이터 JPA
728x90
'BE > JPA' 카테고리의 다른 글
스프링 데이터 JPA - 새로운 엔티티를 구별하는 방법 (0) | 2022.09.14 |
---|---|
스프링 데이터 JPA - 스프링 데이터 JPA 구현체 분석 (0) | 2022.09.14 |
스프링 데이터 JPA - Web 확장 도메인 클래스 컨버터 (0) | 2022.09.14 |
스프링 데이터 JPA - Auditing (0) | 2022.09.14 |
스프링 데이터 JPA - 사용자 정의 리포지토리 구현 (0) | 2022.09.14 |
Comments