페이징 처리

타마타마·2022년 9월 4일
0

JPA

목록 보기
7/10
post-thumbnail

Page 사용

  • MemberRepository.java

    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);
  • MemberRepositoryTest.java

    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();//다음 페이지가 있는지 확인

Slice

Page VS Slice

Page는 totalCount등 페이징 수에 관한 함수를 제공하여 사용할 수 있음 + limit값에 대하여 그대로 쿼리에 사용됨
Slice는 페이징 수에 관련된 함수 제공 X + limit값 +1을 해줌.

  • MemberRepository.java
 Slice<<Member> findByAge(int age, Pageable pageable);
  • MemberRepositoryTest.java
 //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;
}
  • Page번호를 0이 아닌 1부터 시작하게 하고 싶다.>> pageable를 본인이 선언하기
@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 ~? 🥰

0개의 댓글