본문 바로가기
게시판 만들기(Spring Boot, JPA)

게시판 만들기 07 - 페이지네이션

by burpee 2023. 5. 22.

게시판 만들기 세 번째 글에서 게시글 페이징에 대한 내용을 이미 다뤘다. 그런데 그 내용에 보충해서 해야 할 것이 하나 더 생겨서 이 글을 쓰게 됐다.

 

페이지네이션

페이지네이션은 콘텐츠를 여러 페이지로 나누고 버튼을 이용해서 특정 페이지로 이동할 수 있는 UI 요소다.

부트스트랩 페이지네이션

페이지네이션은 어떻게 만들어줄까?

지난 게시판 만들기 포스팅에서 클라이언트가 요청한 페이지 번호에 대해서 해당 페이지의 콘텐츠 리스트를 만들어서 반환해 주는 실습을 해봤다. 그리고 JPA가 반환해 준 Page 객체에서 [ic]getTotalElements()[/ic], [ic]getTotalPages()[/ic], [ic]getNumber()[/ic], [ic]getPageSize()[/ic] 등의 메서드를 통해 총 게시글 수, 총 페이지 수, 현재 페이지, 페이지 크기 등을 확인할 수 있다고 했다. 이렇게 페이지에 관련된 값들을 클라이언트에 내려주면 클라이언트에서 페이지네이션 UI 요소를 만들 수 있을 것이다.

그런데 나는 페이지네이션을 더 좋게, 더 구조적으로 만들기 위해 몇 가지 데이터가 더 필요하다고 생각했다. 예를 들면 page를 5개씩 끊어서 보여주거나 앞, 뒤 페이지의 존재 여부에 따라 prev, next 버튼을 활성화, 비활성화하는 등의 기능을 넣을 때 필요한 데이터 말이다.

그래서 JPA에서 제공해 주는 기본적인 페이지 데이터를 이용하여 내가 필요하다고 생각한 값을 만들어서 클라이언트에게 내려주려고 한다.

 

PagingUtil 클래스

JPA에서 제공해주는 기본 페이지 데이터 4개를 생성자에 넣어서 나머지 데이터들을 set 해주는 방식으로 Util 클래스를 생성할 수 있다.

@Getter
public class PagingUtil {

    // 총 요소 수
    private long totalElements;
    // 총 페이지 수
    private int totalPages;
    // 현재 페이지
    private int pageNumber;
    // 페이지 크기(한 페이지 당 보여줄 컨텐츠 수)
    private int pageSize;
    // 총 페이지 그룹 수(총 20페이지를 5개씩 끊어서 보여준다면 페이지 그룹 수는 4)
    private int totalPageGroups;
    // 페이지 그룹 크기(페이지를 5씩 끊어서 보여준다면 페이지 그룹 크기는 5)
    private int pageGroupSize = 5;
    // 현재 페이지 그룹
    private int pageGroup;
    // 시작 페이지
    private int startPage;
    // 끝 페이지
    private int endPage;
    // 이전 페이지 그룹이 존재하는지 여부
    private boolean existPrePageGroup;
    // 다음 페이지 그룹이 존재하는지 여부
    private boolean existNextPageGroup;

    public PagingUtil(long totalElements, int totalPages, int pageNumber, int pageSize) {
        this.totalElements = totalElements;
        this.totalPages = totalPages;
        this.pageNumber = pageNumber + 1;
        this.pageSize = pageSize;
        this.totalPageGroups = setTotalPageGroups();
        this.pageGroup = setPageGroup();
        this.startPage = setStartPage();
        this.endPage = setEndPage();
        this.existPrePageGroup = setExistPrePageGroup();
        this.existNextPageGroup = setExistNextPageGroup();
    }

    private int setTotalPageGroups() {
        if (this.totalPages % this.pageGroupSize == 0) {
            return this.totalPages / this.pageGroupSize;
        }
        return this.totalPages / this.pageGroupSize + 1;
    }

    private int setPageGroup() {
        if (this.pageNumber % this.pageGroupSize == 0) {
            return this.pageNumber / this.pageGroupSize;
        }
        return this.pageNumber / this.pageGroupSize + 1;
    }

    private int setStartPage() {
        return (this.pageGroup - 1) * this.pageGroupSize + 1;
    }

    private int setEndPage() {
        int endPage = this.pageGroup * this.pageGroupSize;
        if (this.totalPages < endPage) {
            return this.totalPages;
        }
        return endPage;
    }

    public boolean setExistPrePageGroup() {
        if (this.pageGroup > 1) {
            return true;
        }
        return false;
    }

    public boolean setExistNextPageGroup() {
        if (this.pageGroup < this.totalPageGroups) {
            return true;
        }
        return false;
    }
}

 

 

클라이언트에게 이 객체를 만들어서 전달해주면 페이지네이션을 만들 때 유용하게 사용할 수 있을 것이다.

 


소스코드

https://github.com/cheoljin408/simple-board-api

 

GitHub - cheoljin408/simple-board-api

Contribute to cheoljin408/simple-board-api development by creating an account on GitHub.

github.com

 

연관 글

https://burpeekim.tistory.com/6

 

게시판 만들기 03 - 게시글 페이징

페이징 처리 하는 이유 여러 사이트를 돌아다니다 보면 아래 사진과 같은 걸 본 적이 분명히 있을 것이다. 이런 페이징 처리는 많은 데이터들을 여러 페이지로 나눠서 제공하므로 데이터를 보는

burpeekim.tistory.com

 

댓글