[Spring Data JPA] - [Web] 확장 페이징과 정렬

홍정완·2022년 8월 2일
0

JPA

목록 보기
22/38
post-thumbnail
post-custom-banner

페이징과 정렬 예제


@GetMapping("/members")
public Page<Member> list(Pageable pageable) {
 	
    Page<Member> page = memberRepository.findAll(pageable);
 	
    return page;
}

  • 파라미터로 Pageable을 받을 수 있다.
  • Pageable은 인터페이스, 실제는 org.springframework.data.domain.PageRequest 객체 생성



요청 파라미터


  • 예) /members?page=0&size=3&sort=id,desc&sort=username,desc
  • page: 현재 페이지, 0부터 시작한다.
  • size: 한 페이지에 노출할 데이터 건수
  • sort: 정렬 조건을 정의한다. 예) 정렬 속성, 정렬 속성...(ASC | DESC), 정렬 방향을 변경하고 싶으면 sort 파라미터 추가 ( asc 생략 가능)

기본값

  • 페이지 설정을 글로벌 환경설정으로 바꿔줄 수 있다. application.yml에 다음 설정을 추가한다.
spring.data.web.pageable.default-page-size=20 /# 기본 페이지 사이즈/
spring.data.web.pageable.max-page-size=2000 /# 최대 페이지 사이즈/

  • 개별 설정
    @PageableDefault(size = 12, sort = “username”) 등의 옵션을 줄 수도 있다.
@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
public String list(

	@Qualifier("member") Pageable memberPageable,
 	@Qualifier("order") Pageable orderPageable, ...



Page 내용을 DTO로 변환하기

  • 엔티티를 API로 노출하면 다양한 문제가 발생한다. 그래서 엔티티를 꼭 DTO로 변환해서 반환해야 한다.
  • Page는 map()을 지원해서 내부 데이터를 다른 것으로 변경할 수 있다.

Member DTO

@Data
public class MemberDto {

 	private Long id;
 	private String username;
 
 	public MemberDto(Member m) {
 		this.id = m.getId();
 		this.username = m.getUsername();
	}

}

Page.map() 사용

@GetMapping("/members")
public Page<MemberDto> list(Pageable pageable) {
 
 	Page<Member> page = memberRepository.findAll(pageable);
 	Page<MemberDto> pageDto = page.map(MemberDto::new);
 
 	return pageDto;
}

Page.map() 코드 최적화

@GetMapping("/members")
public Page<MemberDto> list(Pageable pageable) {

 	return memberRepository.findAll(pageable).map(MemberDto::new);
}



Page를 1부터 시작하기


첫 번째 방법

Pageable, Page를 파리미터와 응답 값으로 사용히지 않고, 직접 클래스를 만들어서 처리한다. 그리고 직접 PageRequest(Pageable 구현체)를 생성해서 Repository에 넘긴다. 물론 응답 값도 Page 대신에 직접 만들어서 제공해야 한다.


두 번째 방법

spring.data.web.pageable.one-indexed-parameters를 true로 yml 파일에 설정한다. 그런데 이 방법은 web에서 page 파라미터를 -1 처리할 뿐이다. 따라서 응답 값인 Page에 모두 0 페이지 인덱스를 사용하는 한계가 있다.



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
}
profile
습관이 전부다.
post-custom-banner

0개의 댓글