본문 바로가기
프로그래밍/SpringBoot

[스프링 부트 게시판] 게시판 리스트 페이징 처리

by 소소로드 2020. 9. 30.

게시판 리스트 페이징 처리


게시판을 만들면 단순히 리스트로 끝까지 보여주고 무제한 스크롤이 되는 것이 아니라,
보기 좋게 목록을 구성해주어야 한다. 이를 페이징 처리라고 부른다.
초반엔 어려워서 애를 먹는 부분이다.

페이징 처리를 위해서는 Criteria라는 객체와 Paging 객체가 필요하다.

Criteria : 페이지 자체를 관리하는 객체로 페이지당 보여줄 개수를 담당한다
Paging : 게시판 하단의 페이징을 담당한다.


Criteria 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Criteria {
    
    // 특정 페이지 조회를 위한 클래스
    private int page; // 현재 페이지 번호
    private int perPageNum; // 페이지당 보여줄 게시글의 개수
    
    public int getPageStart() {
        // 특정 페이지의 범위를 정하는 구간, 현재 페이지의 게시글 시작 번호
        // 0 ~ 10 , 10 ~ 20 이런식으로
        return (this.page -1* perPageNum;
    }
 
    public Criteria() {
        // 기본 생성자 : 최초 게시판에 진입시 필요한 기본값
        this.page = 1;
        this.perPageNum = 10;
    }
 
    // 현재 페이지 번호 page : getter, setter
    public int getPage() {
        return page;
    }
 
    public void setPage(int page) {
        if(page <= 0) {
            this.page = 1;
            
        } else {
            this.page = page;
        }    
    }
 
    
    // 페이지당 보여줄 게시글의 개수 perPageNum : getter, setter
    public int getPerPageNum() {
        return perPageNum;
    }
 
    public void setPerPageNum(int perPageNum) {
        int cnt = this.perPageNum;
        
        if(perPageNum != cnt) {
            this.perPageNum = cnt;    
        } else {
            this.perPageNum = perPageNum;
        }
        
    }
    
    @Override
    public String toString() {
        return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
    }
}
 
cs

this.page = 1;
this.perPageNum = 10;

이 부분에 대한 설정이 처음 들어갔을 때 페이지 표시와 목록에 몇 개나 보여줄지를 설정한다.



Paging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 게시판 하단의 페이징
public class Paging {
    
    private int totalCount; // 게시판 전체 데이터 개수
    private int displayPageNum = 10// 게시판 화면에서 한번에 보여질 페이지 번호의 개수
    
    private int startPage; // 화면의 시작 번호
    private int endPage;  // 화면의 끝 번호
    private boolean prev; // 페이징 이전 버튼 활성화 여부
    private boolean next; // 페이징 다음 버튼 활성화 여부
    
    private Criteria cri;
 
    
    public int getTotalCount() {
        return totalCount;
    }
 
    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
        
        pagingData();
    }
    
    private void pagingData() {
        
        endPage = (int) (Math.ceil(cri.getPage() / (double) displayPageNum) * displayPageNum);
        // endPage = (현재 페이지 번호 / 화면에 보여질 페이지 번호의 개수) * 화면에 보여질 페이지 번호의 개수
        startPage = (endPage - displayPageNum) + 1;
        // startPage = (끝 페이지 번호 - 화면에 보여질 페이지 번호의 개수) + 1
        
        int tempEndPage = (int) (Math.ceil(totalCount / (double) cri.getPerPageNum()));    
        if(endPage > tempEndPage) {
            endPage = tempEndPage;
        }
        // 마지막 페이지 번호 = 총 게시글 수 / 한 페이지당 보여줄 게시글의개수
        
        prev = startPage == 1 ? false : true;    
        // 이전 버튼 생성 여부 = 시작 페이지 번호가 1과 같으면 false, 아니면 true
        next = endPage * cri.getPerPageNum() >= totalCount ? false : true;
        // 다음 버튼 생성 여부 = 끝 페이지 번호 * 한 페이지당 보여줄 게시글의 개수가 총 게시글의 수보다
        // 크거나 같으면 false, 아니면 true
    }
 
    public int getDisplayPageNum() {
        return displayPageNum;
    }
 
    public void setDisplayPageNum(int displayPageNum) {
        this.displayPageNum = displayPageNum;
    }
 
    public int getStartPage() {
        return startPage;
    }
 
    public void setStartPage(int startPage) {
        this.startPage = startPage;
    }
 
    public int getEndPage() {
        return endPage;
    }
 
    public void setEndPage(int endPage) {
        this.endPage = endPage;
    }
 
    public boolean isPrev() {
        return prev;
    }
 
    public void setPrev(boolean prev) {
        this.prev = prev;
    }
 
    public boolean isNext() {
        return next;
    }
 
    public void setNext(boolean next) {
        this.next = next;
    }
 
    public Criteria getCri() {
        return cri;
    }
 
    public void setCri(Criteria cri) {
        this.cri = cri;
    }
    
    
    @Override
    public String toString() {
        return "PageMaker [totalCount=" + totalCount + ", startPage=" + startPage + ", endPage=" + endPage + ", prev="
                + prev + ", next=" + next + ", displayPageNum=" + displayPageNum + ", cri=" + cri + "]";
    }
    
}
 
cs

displayPageNum
이 부분에 대한 설정이 하단 페이징 목록의 1 2 3 ... 10 을 결정한다.
내가 10으로 설정했으면 [1 ~ 10 다음]까지만 하단에 나오고
11페이지 이후부터 [이전 11 ~ 20 다음] 이런식으로 출력된다.



Boardcontroller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 게시판 리스트
    /*@RequestMapping(value="/boardList")
    public String boardList(Model model) throws Exception {
        
        List<BoardVO> list = boardService.boardList();
        model.addAttribute("list", list);
        
        return "boardList";
    }*/
    
    @RequestMapping(value="/boardList")
    public String boardList(Criteria cri, Model model) throws Exception {
 
        // 전체 글 개수
        int boardListCnt = boardService.boardListCnt();
        
        // 페이징 객체
        Paging paging = new Paging();
        paging.setCri(cri);
        paging.setTotalCount(boardListCnt);    
        
        List<Map<String, Object>> list = boardService.boardList(cri);
        
        model.addAttribute("list", list);    
        model.addAttribute("paging", paging);    
                
        return "boardList";
    }
cs

전에 했던 게시판 리스트는 주석처리하거나, 그 위에 페이징 처리 내용을 덧붙여도 된다.

boardListCnt는 mapper.xml에서 count(*)로 총 게시글을 가져오는데,
해당 내용이 필요한 이유는 한 페이지당 보여줄 게시글 수가 필요하기 때문이다.
게시글 수를 paging 객체에 담게 되면 원하는 개수, 시작 페이지 번호 등을 설정할 수 있다.
예를 들어 전체 글이 500개고, 내가 한 페이지에 10개씩 보여준다면 총 50개의 목록수가 필요하다.



Boardservice

1
2
3
4
5
6
7
public int boardListCnt() throws Exception {
            return boardMapper.boardListCnt();
     }
     
     public List<Map<String, Object>> boardList(Criteria cri) throws Exception {
            return boardMapper.boardList(cri);
    }
cs


Boardmapper.java

1
2
3
public List<Map<String, Object>> boardList(Criteria cri) throws Exception;
 
public int boardListCnt() throws Exception;
cs


Boardmapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
 <select id="boardList" resultType="hashmap" parameterType="hashmap">
        <![CDATA[
            SELECT * 
            FROM hello_board
            ORDER BY NUM DESC
            LIMIT #{pageStart}, #{perPageNum}
        ]]>
</select>
<select id="boardListCnt" resultType="int">
        SELECT count(*)
        FROM hello_board
</select>
cs


boardList

1
2
3
4
5
6
7
8
9
10
11
<ul class="paging">
    <c:if test="${paging.prev}">
        <span><a href='<c:url value="/boardList?page=${paging.startPage-1}"/>'>이전</a></span>
    </c:if>
    <c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="num">
        <span><a href='<c:url value="/boardList?page=${num}"/>'>${num}</a></span>
    </c:forEach>
    <c:if test="${paging.next && paging.endPage>0}">
        <span><a href='<c:url value="/boardList?page=${paging.endPage+1}"/>'>다음</a></span>
    </c:if>
</ul>
cs

전 시간에 만든 table 밑에 넣으면 된다.(*주의 : 테이블 안에 넣는 것이 아님.) 

이 부분은 예를 들어 내가 하단 목록의 13번 페이지로 들어갔을 경우
boardList?page=13 이런식으로 표현이 된다.



<완성된 페이징 처리>



전체적인 완성작은 해당 소스를 참고
github.com/yulfsong/spring-boot-hello-project

yulfsong/spring-boot-hello-project

Contribute to yulfsong/spring-boot-hello-project development by creating an account on GitHub.

github.com