16. Web 확장 - 페이징과 정렬

민정·2022년 12월 14일
0

Spring Data JPA

목록 보기
16/17
post-thumbnail
post-custom-banner

✨ 페이징

파라미터 : Pageable

@RestController
@RequiredArgsConstructor
public class MemberController {
    private final MemberRepository memberRepository;

 	@GetMapping("/members")
    public Page<Member> list(Pageable pageable){
        Page<Member> page = memberRepository.findAll(pageable);// 모든 함수 pagable 파라미터 넘겨주면 페이징
        return page;
    }

	// 100개의 멤버 데이터 생성
    @PostConstruct
    public void init(){
        for(int i = 0; i< 100; i++){
            memberRepository.save(new Member("user" + i, i));
        }
    }
}

@PostConstruct

스프링 빈의 이벤트 사이클

스프링 컨테이너 생성 - 스프링 빈 생성 - 의존관계 주입 - 초기화 콜백 - 사용 - 소멸 전 콜백 - 스프링 종료

@PostConstruct : 초기화 콜백
@PreDestroy : 소멸 전 콜백

위에서는 의존관계 주입이 끝나고, 멤버 100명의 데이터를 초기화하기 위해서 사용했다.


✨ 페이징

HTTP 요청이 파라미터로 바인딩될 때, Spring Data JPA는 파라미터가 Pageable이면 PageRequest 객체를 생성해서 값을 채워서 Injection을 해준다.

요청 파라미터

page : 현재 페이지 (0 부터 시작)
size : 한 페이지에 노출할 데이터 건수
sort : 정렬 조건(정렬 속성, 정렬 방향 - asc 생략 가능)

예시

/members?page=0 : 0번 페이지 가져오기
/members?page=0&&size=3 : 한 페이지에 3개씩, 0번 페이지 가져오기
/members?page=0&&sort=id,desc : id를 내림차순으로 정렬했을 때, 0번 페이지 가져오기

여러개 sorting

/members?page=0&&sort=id,desc&&sort=username : id를 내림차순으로, username을 오름차순으로 정렬했을 때, 0번 페이지 가져오기


✅ 결과 - 엔티티 직접 반환

요청 : /members?page=0

{
    "content": [
        {
            "createdDate": "2022-12-14T21:47:03.10654",
            "lastModifiedDate": "2022-12-14T21:47:03.10654",
            "createdBy": "143aba9c-f452-45c0-bf3c-17b87ff13182",
            "lastModifiedBy": "143aba9c-f452-45c0-bf3c-17b87ff13182",
            "id": 1,
            "username": "user0",
            "age": 0,
            "team": null
        },
      
      ...
      
      {
            "createdDate": "2022-12-14T21:47:03.40254",
            "lastModifiedDate": "2022-12-14T21:47:03.40254",
            "createdBy": "668bec85-0a56-4185-96f3-2f40fbd430d2",
            "lastModifiedBy": "668bec85-0a56-4185-96f3-2f40fbd430d2",
            "id": 20,
            "username": "user19",
            "age": 19,
            "team": null
        }
    ],
    "pageable": {
        "sort": {
            "empty": true,
            "sorted": false,
            "unsorted": true
        },
        "offset": 0,
        "pageNumber": 0,
        "pageSize": 20,
        "paged": true,
        "unpaged": false
    },
    "last": false,
    "totalPages": 5,
    "totalElements": 100,
    "size": 20,
    "number": 0,
    "sort": {
        "empty": true,
        "sorted": false,
        "unsorted": true
    },
    "first": true,
    "numberOfElements": 20,
    "empty": false
}

last, totalPages, totalElements 등의 내용들은 반환타입이 Page라서 생긴다!


✨ Page 내용 DTO로 변환


🚨 엔티티는 외부에 절대로 그대로 반환하면 안된다!

=> 엔티티의 스펙을 변경하는 순간 API 스펙도 변경됨.

 @GetMapping("/members")
    public Page<MemberDto> list(@PageableDefault(size=12, sort = "username", direction = Sort.Direction.DESC) Pageable pageable){
    
        Page<Member> page = memberRepository.findAll(pageable);// 모든 함수 pagable 파라미터 넘겨주면 페이징
        Page<MemberDto> map = page.map(MemberDto::new);
        return map;
    }

✅ 결과 - DTO 반환

요청 : /members?page=0&&size=3&&sort=id,desc

{
    "content": [
        {
            "id": 100,
            "username": "user99",
            "teamName": null
        },
        {
            "id": 99,
            "username": "user98",
            "teamName": null
        },
        {
            "id": 98,
            "username": "user97",
            "teamName": null
        }
    ],
  
    "pageable": {
        "sort": {
            "empty": false,
            "sorted": true,
            "unsorted": false
        },
        "offset": 0,
        "pageSize": 3,
        "pageNumber": 0,
        "paged": true,
        "unpaged": false
    },
    "last": false,
    "totalPages": 34,
    "totalElements": 100,
    "size": 3,
    "number": 0,
    "sort": {
        "empty": false,
        "sorted": true,
        "unsorted": false
    },
    "first": true,
    "numberOfElements": 3,
    "empty": false
}

✨ 기본 size 개수 설정

global 설정

application.yml

spring.data.web.pageable.default-page-size=20 /# 기본 페이지 사이즈/
spring.data.web.pageable.max-page-size=2000 /# 최대 페이지 사이즈/

개별 설정

@PageableDefault 사용

global 설정보다 개별 설정이 우선한다.

Controller

    @GetMapping("/members")
    public Page<Member> list(@PageableDefault(size=12, sort = "username", direction = Sort.Direction.DESC) Pageable pageable){
        Page<Member> page = memberRepository.findAll(pageable);// 모든 함수 pagable 파라미터 넘겨주면 페이징
        return page;
    }

✨ 접두사

페이징 정보가 둘 이상이면 접두사로 구분한다!

@Qualifier에 접두사명을 추가하면 된다

ex) /members?member_page=0&order_page=1

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


출처

김영한 강사님 - 인프런 실전! 스프링 데이터 JPA

https://velog.io/@limsubin/Spring-Boot%EC%97%90%EC%84%9C-PostConstruct-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90

post-custom-banner

0개의 댓글