반응형
Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다.
Web 확장 - 페이징과 정렬
페이징 정렬 예제
- MemberController.class
@GetMapping("/members")
public Page<Member> list(Pageable pageable) { // pageable 파라미터 정보 , Page 결과 정보
Page<Member> page = memberRepository.findAll(pageable);
return page;
}
@PostConstruct
public void init() {
for(int i = 0; i < 100; i++) {
memberRepository.save(new Member("user" + i, i));
}
}
위 코드를 작성하고 애플리케이션을 실행 후 브라우저에 주소를 입력하면 JSON 데이터를 확인할 수 있다.
여기에서 주소창 맨 뒤에 ?page=0을 입력하면 놀라운 결과를 확인할 수 있다.
?page=값
// 참고로 page의 값은 0부터 시작한다.
데이터를 알아서 20개까지만 가져와서 데이터를 출력한다. page의 값을 1 로주면 21~40까지의 데이터를 출력한다.
더 놀라운 기능은 page=값 뒤에 &size=값을 입력하면 데이터가 출력되는 갯수까지 지정할 수 있다.
&size=값
이런 동작이 어떻게 가능한걸까? Pageable은 인터페이스이다. 스프링 데이터 JPA의 기능을 가져와 스프링 부트에서 세팅을 해준다. 컨트롤러에서 HTTP 파라미터들이 바인딩될 때, pageable이 있으면 PageRequest라는 객체를 생성해서 값을 채워서 인젝션을 해준다.
정렬
정렬은 페이징과 비슷하게 파라미터로 값을 지정해준다.
"&sort=기준,desc(asc)
//asc는 생략 가능
또 sort 조건도 여러 개 추가가 가능하다.
http://localhost:8080/members?page=0&size=3&sort=id,desc&sort=username,desc
기본 값 변경
global 설정
- application.yml
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
# dialect: org.hibernate.dialect.Oracle10gDialect
format_sql: true
# show_sql: true
data:
web:
pageable:
default-page-size: 10
max-page-size: 2000
- default-page-size : 기본으로 보여 줄 데이터 사이즈
- max-page-size : 최대 페이지 사이즈
개별 설정
- MemberController.class
@GetMapping("/members")
public Page<Member> list
(@PageableDefault(size = 5, sort="username") Pageable pageable) {
Page<Member> page = memberRepository.findAll(pageable);
return page;
}
global 설정보다 개별 설정이 더 우선순위가 높다. 주소창에 page=0으로 입력하면 username이 오름차순으로 5개의 데이터가 출력된 걸 볼 수 있다.
접두사
- 페이징 정보가 둘 이상일 때 접두사로 구분한다.
- @Qualifier에 접두사 추가 "{접두사명}_xxx"
public String list(
@Qualifier("member") Pageable memberPageable,
@Qualifier("order") Pageable orderPageable,
.... 생략
Page 내용을 DTO로 변환
- 엔티티를 API로 노출하면 다양한 문제가 발생할 수 있다. 그래서 엔티티를 꼭 DTO로 변환해서 반환해야 한다.
- Page는 map()을 지원해서 내부 데이터를 다른 것으로 변경할 수 있다.
- MemberController.class
MemberDto는 전에 만들었던 클래스를 이용한다.
@GetMapping("/members")
public Page<MemberDto> list
(@PageableDefault(size = 5, sort="username") Pageable pageable) {
Page<Member> page = memberRepository.findAll(pageable);
Page<MemberDto> map =
page.map(member -> new MemberDto(member.getId(), member.getUsername(), null));
return map;
}
어우 근데 아무래도 map을 만드는 코드 안에 member.getId()..어쩌구 저쩌구를 다 넣기엔 코드가 너무 지저분하다. 조금 더 깔끔하게 다져보자.
- MemberDto.class
public MemberDto(Member member) {
this.id = member.getId();
this.username = member.getUsername();
this.teamName = null;
}
- MemberController.class
@GetMapping("/members")
public Page<MemberDto> list
(@PageableDefault(size = 5, sort="username") Pageable pageable) {
Page<MemberDto> map = memberRepository.findAll(pageable)
.map(MemberDto::new);
return map;
Page 1부터 시작하기
스프링 데이터 JPA에서 Page는 0부터 시작한다. 1부터 시작하려면 어떻게 해야 할까?
- Pageable, Page를 파라미터와 응답 값으로 사용하지 않고, 직접 클래스를 만들어서 처리. 그리고 직접 PageRequest를 생성해서 리포지토리에 넘긴다. 물론 응답 값도 Page 대신에 직접 만들어서 제공해야 한다.
- spring.data.web.pageable.one-indexed-parameters를 true로 설정한다. 그런데 이 방법은 web에서 page 파라미터를 -1 처리할 뿐이다. 따라서 응답 값인 Page에 모두 0 페이지 인덱스를 사용하는 한계점이 있다.
그러므로 첫 번째를 방법을 사용하면 된다!
반응형