스프링부트 입문기 #4 - 페이징

HanSH·2023년 7월 4일
0

SpringBoot 삽질기

목록 보기
6/12

이번에는 페이징을 구현해 볼 것이다.
순수 JPA를 이용해서...

repository 수정

// PostRepository.java
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
    Page<Post> findAllByOrderByIdDesc(Pageable pageable);
}

페이징을 이용하기 위해서는 Pageable 인터페이스를 이용하도록 한다.
해당 인터페이스를 이용하면 페이지 번호, 페이지 크기, 정렬 순서 정볼르 이용하여 Paging을 쿼리 없이 사용할 수 있다!

주요 메소드로는

  • int getPageNumber(): 현재 페이지 번호를 반환
  • int getTotalPages(): 전체 페이지 수를 반환
  • Page<T> getContent(): T 타입의 Page 객체 반환

이 있다.
자세한 것은 docs

레포지토리를 위와 같이 작성하면 모든 데이터를 ID를 기준으로 내림차순 한 후, 페이징을 이용하여 값을 가져오게 된다.

response 수정

기존에 사용하는 Response DTO에는 전체 페이지 수를 반환하지 않는다.
따라서 전체 페이지 수를 같이 반환할 수 있도록 아래와 같이 수정하자.

// PostResponse.java
@Getter
@Setter
@AllArgsConstructor
public class PostResponse {
    public Integer counts;
    public List<ResponseData> data;

    public PostResponse() {
        data = new ArrayList<>();
    }
    
    public PostResponse(Integer counts) {
        this.counts = counts;
        data = new ArrayList<>();
    }

    @AllArgsConstructor
    public static class ResponseData {
        public Long id;
        public String title;
        public String content;
    }
}

빈 생성자로는 ArrayList만 생성하고, counts가 있는 생성자로는 counts를 초기화 및 ArrayList를 생성한다.
내부에 ResponseData 클래스를 하나 생성하고, 해당 클래스를 데이터로 갖는 List를 생성한다.

service 수정

Pageable을 사용하기 위해 Pageable 변수를 초기화하는 과정을 가진다.

    public PostResponse getPage(Integer pageNo) {
        Pageable pageable = PageRequest.of(pageNo, 10);
        Page<Post> page = postRepository.findAllByOrderByIdDesc(pageable);

        PostResponse res = new PostResponse(page.getTotalPages());
        page.getContent().forEach( post -> res.data.add(new PostResponse.ResponseData(post.getId(), post.getTitle(), post.getContent())));

        return res;
    }
  • Pageable pageable = PageRequest.of(pageNo, 10);
    Pageable 클래스를 초기화하는 과정.
    페이지 번호와 몇 개씩 조회할 것인지를 설정한다.

  • page.getContent().forEach( post -> res.data.add(new PostResponse.ResponseData(...)));
    페이징한 결과를 Response에 맞게 수정한다.

controller 수정

// PostController.java
    @GetMapping("")
    public ResponseEntity<PostResponse> getPosts(@RequestParam("pages") Integer pageNo) {
        PostResponse page = postService.getPage(pageNo);
        return ResponseEntity.status(HttpStatus.OK).body(page);
    }

이로서 얻은 페이징 결과값을 반환을 한다.
/posts?pages=0 결과를 한번 보자.

{
    "counts": 2,
    "data": [{
            "id": 157,
            "title": "asdf11",
            "content": "qwer11"
        }, {
            "id": 156,
            "title": "asdf10",
            "content": "qwer10"
        }, {
            "id": 155,
            "title": "asdf9",
            "content": "qwer9"
        }, {
            "id": 154,
            "title": "asdf8",
            "content": "qwer8"
        }, {
            "id": 153,
            "title": "asdf7",
            "content": "qwer7"
        }, {
            "id": 152,
            "title": "asdf6",
            "content": "qwer6"
        }, {
            "id": 103,
            "title": "asdf5",
            "content": "qwer5"
        }, {
            "id": 102,
            "title": "asdf4",
            "content": "qwer4"
        }, {
            "id": 53,
            "title": "asdf3",
            "content": "qwer3"
        }, {
            "id": 52,
            "title": "asdf2",
            "content": "qwer2"
        }
    ]
}

정상적으로 반환됨을 볼 수 있다!

pages=3인 경우, {"counts":2,"data":[]} 결과가 나온다.

추가 수정

PostResponse DTO를 수정하였으니, UserController의 getUserWritingDetail를 수정하자.

// UserController.java
    private List<PostResponse.ResponseData> getUserWritingDetail(List<Post> p) {
        List<PostResponse.ResponseData> res = new ArrayList<>();
        p.forEach(a -> res.add(new PostResponse.ResponseData(a.getId(), a.getTitle(), a.getContent())));
        return res;
    }

이로서 페이징을 완료하였다.
만세!

profile
저는 말하는 싹 난 감자입니다

0개의 댓글