repository가 JpaRepository를 상속받고 있는 경우, findAll(pageable)해주면 페이징 처리가 바로 가능.
만약 findByAge와 같이 특정 파라미터로 데이터 추출해주는 쿼리라면 findByAge(파라미터1, 파라미터2, . . . pageable)해준다.
pageable은 가장 마지막에 사용할 것
/*
여러개의 테이블이 join되어 있을 때 단순 Page로 count처리를 하게 된다면
countQuery에도 join이 걸릴 수 있음 ==> 성능 👎🏻
그럴 경우 countQuery는 @Query를 사용하여 따로 설정해줌.
@Query(value="select m from Member m",
countQuery = "select count(m) from Member m")
*/
Page<Member> findByAge(int ange, Pageable pageable);
1. JPA에서 페이지 처리할 때 첫번째 페이지 index번호는 0
//given
memberRepository.save("memberA", 10);
memberRepository.save("memberB", 10);
memberRepository.save("memberC", 10);
memberRepository.save("memberD", 10);
int age = 10;
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));
//when
Page<Member> page = memberRepository.findByAge(age, pageRequest);
//then
Page<MemberDto> toMap = page.map(m -> new MemberDto(m.getId(), m.getUsername(), m.getTeam().getUsername());
//Controller에서 반환하게 됐을 때 Entity가 아닌 Dto를 넘겨주어야 함.
List<Member> content = page.getContent();
long totalElemnets = page.getTotalElements();
assertThat(content.size()).isEqualTo(3);//컨텐츠 나오는 개수
assertThat(page.getTotalElements()).isEqualTo(5);//
assertThat(page.getNumber()).isEqualTo(0);//페이지 번호 가져올 수 있음 (page.getNumber())
assertThat(page.getTotalPages()).isEqualTo(2);//전체 페이지 개수 (page.getTotalPages())
assertThat(page.isFirst()).isTrue();//첫번째 페이지인지 확인
assertThat(page.hasNext()).isTrue();//다음 페이지가 있는지 확인
Page는 totalCount등 페이징 수에 관한 함수를 제공하여 사용할 수 있음 + limit값에 대하여 그대로 쿼리에 사용됨
Slice는 페이징 수에 관련된 함수 제공 X + limit값 +1을 해줌.
Slice<<Member> findByAge(int age, Pageable pageable);
//Page사용 시 //given까지는 동일
//when
Slice<Member> sliceP = memberRepository.findByAge(age, pageRequest);
//then
List<Member> content = sliceP.getContent();
//long totalElements = slicep.getTotalElements();
assertThat(content.size()).isEqualTo(3);//컨텐츠 나오는 개수
//assertThat(sliceP.getTotalElements()).isEqualTo(5);// >> Slice에서 사용 X
assertThat(sliceP.getNumber()).isEqualTo(0);//페이지 번호 가져올 수 있음 (page.getNumber())
//assertThat(sliceP.getTotalPages()).isEqualTo(2);// >> Slice에서 사용 X
assertThat(sliceP.isFirst()).isTrue();//첫번째 페이지인지 확인
assertThat(sliceP.hasNext()).isTrue();//다음 페이지가 있는지 확인
-MemberDto.jaa
@Getter
public class MemberDto {
private Long id;
private String username;
private String teamName;
public MemberDto(Long id, String username) {
this.id = id;
this.username = username;
}
//Dto는 entity를 참조해도 상관 X
public MemberDto(Member member){
this.id= member.getId();
this.username = member.getUsername();
}
}
-MemberController.java
- localhost:8080/members?page=1&size=3&sort=username,desc
members뒤에 ?page=1&size=3&sort=username,desc넣어서 사용 가능
page : 페이지 번호 , size : 한 페이지에 몇개 조회할지, sort : sort 할 것 >> 안할 경우는 default가 20개 가져옴
default 값 변경하려면 application.yml변경 or 해당 메서드에만 특정 값 줄 땐 @PageableDefault 사용
@GetMapping("/members")
public Page<MemberDto> list(@PageableDefault(size=5) Pageable pageable){
Page<Member> page = memberRepository.findAll(pageable);
Page<MemberDto> pageDto = page.map(MemberDto::new);//항상 DTO로 변환하여 반환할 것!
return pageDto;
}
@GetMapping("/members/pagingNumOne")
public Page<MemberDto> listPageNumOne(@PageableDefault(size=5) Pageable pageable){
PageRequest request = PageRequest.of(1, 2);
Page<Member> page = memberRepository.findAll(request);
Page<MemberDto> pageDto = page.map(MemberDto::new);
return pageDto;
}
.
.
.
순수 JPA를 사용하여 페이징 처리를 할 땐 쿼리에서 데이터를 받고 페이징처리 로직을 짜기 귀찮았는데 Spring dataJPA는 너무 효율적으로 처리를 해주는 것 같다. ㅋㅋ
너무 고마운girl ~? 🥰