스프링 - Pageable

kwak woojong·2022년 7월 4일
0

코드스테이츠

목록 보기
28/36
post-thumbnail

스프링 Pageable를 이용하면 페이징을 쉽게 구현할 수 있다.

@GetMapping
    public ResponseEntity getMembers(@PageableDefault(sort = "memberId", direction = Sort.Direction.DESC) Pageable pageable) {
    
        Page<Member> page = memberService.findMembers(pageable);
        PageGetResponseDto response = mapper.pageToResponseDto(page);

        return new ResponseEntity<>(response, HttpStatus.OK);
    }

상기 코드는 /members에 Get 요청을 하면 실행된다.

Pageable을 통해 불러올 페이지, 한페이지에 몇개의 데이터를 보여주는 사이즈를 파라미터로 받아온다.

localhost:8080/v10/members?size=5&page=1

즉 위 주소는 5개씩 데이터를 가져오는데 1페이지를 보여주는 쿼리를 만들어준다.

public interface MemberRepository extends CrudRepository<Member, Long> {
    Optional<Member> findByEmail(String email);
    Page<Member> findAll(Pageable pageable);
}

jpa가 아닌 jdbc를 쓴 상황임... 원래 jpa를 자주 쓰는데 교육 받는다고 jdbc를 썼다.

엄밀히 말하면 스프링data jdbc인 상황임.

스프링data jpa에서도 잘 먹으니까 여기서도 뭐 잘 되겠지

public Page<Member> findMembers(Pageable pageable) {
        return memberRepository.findAll(pageable);
    }

서비스 클래스에서도 간단하게 작성해준다.

pageable page, size 즉 offset, limit가 다 잡혀 있으니까

이래 넘겨도 될 거임

public class PageGetResponseDto {

    private List<Member> data;
    private PageInfo pageInfo;
}

ResponseEntity에 빼기 편하게 하려고 Dto 클래스를 만들어준다.
data는 Page의 content를 가져갈가고 PageInfo는 페이지, 사이즈, 토탈데이터수, 토탈페이지를 가져갈거다.

public class PageInfo {
    private int page;
    private int size;
    private int totalElements;
    private int totalPages;
}

맵퍼 클래스를 써줘야 한다.

@Mapper(componentModel = "spring")
public interface MemberMapper {
    Member memberPostDtoToMember(MemberPostDto memberPostDto);
    Member memberPatchDtoToMember(MemberPatchDto memberPatchDto);
    MemberResponseDto memberToMemberResponseDto(Member member);
    List<MemberResponseDto> membersToMemberResponseDtos(List<Member> members);

    default PageGetResponseDto pageToResponseDto(Page<Member> page) {
        PageGetResponseDto pageGetResponseDto
                = new PageGetResponseDto(
                        page.getContent(),
                new PageInfo(page.getNumber() + 1, page.getSize(), page.getNumberOfElements(), page.getTotalPages())
        );


        return pageGetResponseDto;
    }

}

아직 mapper 사용에 익숙치 않아서 그냥 디폴트로 선언해서 수동으로 만들어줬다.

쿼리도 잘 나가고 결과값도 만족스러움.

페이지에 -2도 넣어봤는데, 알아서 0으로 잡아줬다.

그리고 페이지는 0부터 시작이기 때문에 몇가지 옵션을 부여했다.

우선 pageInfo 맵핑땐 +1을 달아줬고, Pageable 내부 옵션을 바꿔줌


(@PageableDefault(sort = "memberId", direction = Sort.Direction.DESC) Pageable pageable)

memberId로 sort할건데, 방향이 내림차순이야 라고 선언해줬다.

이 외에도 size나 page도 조절 가능하니 참고

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/web/PageableDefault.html


파라미터가 0으로 들어오고 0페이지가 보여서 헷갈리는 부분은

application.properties에서 옵션을 좀 넣어주면 된다.

yml방식

spring:
  data:
    web:
      pageable:
        one-indexed-parameters: true

이걸로 해결할 수 있다.
one-indexed-parameters를 true로 하면 1부터 셈.

물론 쿼리는 알아서 0으로 나가고, 상기 Page의 page필드도 0이니까 조절이 조금 필요하긴 하다.

# DATA WEB (SpringDataWebProperties)
spring.data.web.pageable.default-page-size=20         # Default page size.
spring.data.web.pageable.max-page-size=2000           # Maximum page size to be accepted.
spring.data.web.pageable.one-indexed-parameters=false # Whether to expose and assume 1-based page number indexes.
spring.data.web.pageable.page-parameter=page          # Page index parameter name.
spring.data.web.pageable.prefix=                      # General prefix to be prepended to the page number and page size parameters.
spring.data.web.pageable.qualifier-delimiter=_        # Delimiter to be used between the qualifier and the actual page number and size properties.
spring.data.web.pageable.size-parameter=size          # Page size parameter name.
spring.data.web.sort.sort-parameter=sort              # Sort parameter name.

속성으로는 위와 같은 친구들이 있으니까 참고해서 잘 쓰자.

application.properties에서 설정하면 글로벌 옵션이 되니까 참고

profile
https://crazyleader.notion.site/Crazykwak-36c7ffc9d32e4e83b325da26ed8d1728?pvs=4<-- 포트폴리오

0개의 댓글