본문 바로가기
JAVA/spring

paging processing (페이징 처리)- 3

by 개폰지밥 2019. 8. 9.
반응형

코드로 배우는 스프링 웹 프로젝트를 보면서 따라함

화면 하단의 페이징 처리

브라우저 상에서 URI와 파라미터를 조절하는 결과가 온전하게 나온다면 화면 하단에 나오는 페이지 번호가 출력되는 작업을 진행합니다.

화면에서 페이징 처리한 결과를 보여주기 위해서는 반드시 몇 개의 데이터가 필요합니다.

-       시작 페이지 번호(srtartPage) – 예를 들어 화면상에 10개의 페이지 번호를 출력한다고 했을 때, 현재 페이지가 1에서 10의 사이에 있는 번호라면 시작 페이지는 1이 되어야 합니다. 만일 시작 페이지의 번호가 1이 아니라면 이전(pref)’으로 갈 수 있는 링크가 제공되어야 합니다.

-       끝 페이지 번호(endPage) – 시작 페이지 번호부터 몇 개의 번호를 보여줘야 하는지를 결정해야 합니다. 이때 영향을 미치는 것이 전체 데이터의 개수입니다. 예를 들어 전체 데이터가 65개이고, 현재 페이지가 5페이지라면 시작 페이지 번호는 1이고, 끝 페이지 번호는 7(65개이므로 7페이지까지는 표시)이 돼야 합니다.

-       전체 데이터의 개수(totalCount) – 끝 페이지 번호를 게산할 때 전체 데이터의 개수를 이용해서 최종적으로 끝 페이지의 번호가 결정됩니다. 만일 끝 페이지 번호보다 많은 양의 데이터가 존재하면 뒤로(next) 갈 수 있는 링크가 추가로 붙게 됩니다.

-       이전 페이지 링크(prev) – 맨 앞의 페이지 번호가 1이 아니라면 화면상에 링크를 통해서 이전 페이지를 조회할 수 있어야만 합니다.

-       이후 페이지 링크(next) – 맨 뒤의 페이지 이후에 더 많은 데이터가 존재하는 경우 이동이 가능하도록 링크를 제공합니다.

 

예를 들어 목록 페이지에서 한 번에 10개의 데이터가 출력되는 상황이고, totalCount122개라고 가정해 보면 다음과 같은 계산이 가능합니다.

-       Page(페이지 번호) 3인 경우

n  startPage 1, endPage10, nexttrue, prevfalse

-       page10인 경우

n  startPage1, endPage10, nexttrue, prevfalse

-       page11인 경우

n  startPage11, endPage13, nextfalse, prevtrue

이와 같은 계산을 위해서는 약간의 산술적인 계산과 순서가 필요합니다. 위의 계산 순서는 다음과 같습니다.

-       먼저 한 페이지에 몇 개의 데이터를 보여주는지(perPageNum) 결정돼 있어야 합니다. 일반적으로 10을 기준으로 생각하는 것이 가장 간단합니다.

-       페이지 번호를 몇 개씩 보여주는지 결정돼 있어야 합니다. 일반적으로 10일 기준으로 하지만, 경우에 따라서 5개씩 페이지 번호가 출력되거나 현재 페이지에서 앞으로 몇 개, 뒤로 몇 개를 보여주는 방식 등도 사용됩니다. 일반적으로 10개씩 화면에 페이지 번호를 보여주는 경우가 많습니다.

-       페이지의 계산: 현재 페이지가 13페이지인 경우 startPage11페이지가 돼야 하고, endPage20이 돼야 합니다.

n  13/10(페이지 번호를 몇 개씩 보여 줄 것인가)=1.3

n  1.3의 올림 = 2

n  2의 의미는 페이지 번호 10개씩 두 번째로 보여지는 페이지라는 것. 즉 화면상의 페이지 번호는 11페이지에서 20페이지라는 의미

n  2*10(페이지 번호 수의 개수)=20

n  20endPage의 번호

n  20-9=11

-       11은 시작 페이지 번호

n  endPage는 전체 데이터의 수인 totalCount의 영향을 많이 받습니다. 예를 들어 startPage11이고, totalCount122라면 endPage13이 돼야만 합니다.

n  endPage에 대한 계싼이 끝나고 나면 다음(next) 페이지의 존재 여부를 결정합니다.

 

endPage 구하기

흔히들 처음에 구해야 하는 것이 startPage라고 생각하지만, endPage를 구하는 것이 산술적인 계산이 더 편할 수 있습니다. endPage는 현재의 페이지 번호를 기준으로 계산합니다.

endPage = (int) (Math.ceil(cri.getPage() / (double)displayPageNum)*displayPageNum);

                       현재 페이지 번호                  페이지 번호의 수

 

위의 공식에서 cri.getPage()는 현재 페이지의 번호를 의미합니다.

-       현재 페이지가 3일 때 : Math.ceil(3/10)*10 = 10

-       현재 페이지가 1일 때 : Math.cil(1/10)*10 = 10

-       현재 페이지가 20일 때: Math.ceil(20/10)*10 = 20

-       현재 페이지가 21일 때: Math.ceil(21/10)*10 = 30

 

startPage 구하기

totalCountendPage의 재계산

totalCount:전체 데이터의 개수

perPageNum: 한번에 보여지는 데이터의 수

이전에 구한 endPage 값과 계산된 결과를 비교해서, 계산된 결과가 작은 경우에는 실제 endPage는 최종 계산된 결과가 돼야만 합니다.

Int tempEndPage = (int)(Math.ceil(totalCount / (double)cri.getPerPageNum())));

….

Prevnext의 계산

페이징 처리용 클래스 설계하기

위의 계산을 매번 jsp 등에서 처리할 수도 있곘지만, 좀 더 편하게 사용하기 위해서는 별도의 클래스를 설계해서 처리하는 것이 좋습니다. 클래스로 설계할 경우 모든 페이징 처리가 필요한 화면에서 쉽게 사용할 수 있기 때문에 대부분 회사에서는 이를 처리하는 클래스를 이미 작성해 둔 경우가 많습니다.

 

클래스의 작성을 위해서 필요한 데이터를 점검해 보면 다음과 같습니다.

-       외부에서 입력되는 데이터(org.zerock.domain.Criteria에 이미 존재)

n  Page: 현재 조회하는 페이지의 번호

n  perPageNum: 한 페이지당 출력하는 데이터의 개수

-       DB에서 계산되는 데이터

n  totalCount:SQL의 결과로 나온 데이터의 전체 개수

-       계산을 통해서 만들어지는 데이터

n  StartPage

n  endPage

n  prev

n  next

위의 정보 중 반드시 필요한 정보는 org.zerock.domain.Criteria가 가진 정보와 sql을 통해서 계산된 totalCount입니다. 이를 이용해서 클래스를 작성한다면 아래와 같은 형태가 될 수 있습니다.

Orz.zerock.domain.PageMaker의 일부

package org.zerock.domain;

 

public class PageMaker {

 

        private int totalCount;

        private int startPage;

        private int endPage;

        private boolean prev;

        private boolean next;

 

        private int displayPageNum = 10;

 

        private Criteria cri;

 

        public void setCri(Criteria cri) {

               this.cri = cri;

        }

 

        public void setTotalCount(int totalCount) {

               this.totalCount = totalCount;

               calcData();

        }

 

        private void calcData() {

               // TODO Auto-generated method stub

               endPage = (int) (Math.ceil(cri.getPage() / (double) displayPageNum) * displayPageNum);

               startPage = (endPage - displayPageNum) + 1;

               int tempEndPage = (int) (Math.ceil(totalCount / (double) cri.getPerPageNum()));

 

               if (endPage > tempEndPage) {

                       endPage = tempEndPage;

               }

               prev = startPage == 1 ? false : true;

               next = endPage * cri.getPerPageNum() >= totalCount ? false : true;

 

        }

 

        public int getTotalCount() {

               return totalCount;

        }

 

        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 int getDisplayPageNum() {

               return displayPageNum;

        }

 

        public void setDisplayPageNum(int displayPageNum) {

               this.displayPageNum = displayPageNum;

        }

 

        public Criteria getCri() {

               return cri;

        }

 

        @Override

        public String toString() {

               return "PageMaker [totalCount=" + totalCount + ", startPage=" + startPage + ", endPage=" + endPage + ", prev="

                              + prev + ", next=" + next + ", displayPageNum=" + displayPageNum + ", cri=" + cri + "]";

        }

 

}

 

 

displayNum은 화면에 보여지는 페이지 번호의 숫자를 의미하는 변수를 추가했습니다. 아래 그림의 경우 displayNum 값이 10인 경우에 10개의 페이지 번호가 출력되는 것을 알 수 있습니다.

<< 

11

12

13

14

15

16

17

18

19 20 >>

만일 화면상의 페이지의 번호가 5개씩만 보여지고 싶다면 해당 값을 변경해주면 됩니다.

 

가장 중요한 계산은 totalCount가 설정되는 시점에 calcData()를 실행해서 계산합니다.

Public void setTotalCount(int totalCount){

This.totalCount = totalCount;

calcData();

}

 

 

BoardController와 뷰처리

Orz.zerock.domain.PageMaker는 실제 화면에서 올바르기 동작하는지 확인하기 위해서 sql의 작성을 조금 뒤로 하고, 컨트롤러에 메소드를 추가해서 확이 ㄴ해보도록 합니다.

실행 여부를 판단하기 위해서 하는 작업이므로 totalCount 값은 임의의 값으로 지정하고 테스트 합니다.

추가된 listPage()Criteria cri를 파라미터로 사용하고, Model 객체를 이용해서 발생하는 PageMaker를 저장합니다.

listPage()에서는 크게 목록 데이터를 Model에 저장하는 작업과, PageMaker를 구성해서 Model에 담는 작업이 이루어집니다.

코드로 추가한 부분의 구조는 아래와 같이 만들어 지게 됩니다.

listPage.jsp의 처리

페이징 처리에 필요한 모든 데이터가 담긴 PageMaker는 최종적으로 listPage.jsp를 이용해서 보여지게 됩니다. 페이징 처리된 결과를 아래와 같은 형태로 부트스트랩의 css를 이용해서 처리됩니다.

1

2

3

4

5

6

7

8

9

10 >>

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<%@ page session="false"%>

<%@include file="../include/header.jsp"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="EUC-KR">

<title>Insert title here</title>

</head>

<body>

        <div class="text-center">

               <ul class="pagination">

                       <c:if test="${pageMaker.prev}">

                              <li><a href="listPage?page=${pageMaker.startPage-1}">&laquo;</a></li>

                       </c:if>

 

                       <c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}"

                              var="idx">

                              <li <c:out value="${pageMaker.cri.page == idx?'class=active':''}"/>>

                                      <a href="listPage?page=${idx}">${idx}</a>

                              </li>

                       </c:forEach>

 

                       <c:if test="${pageMaker.next && pageMaker.endPage >0}">

                              <li><a href="listPage?page=${pageMaker.endPage +1}">&raquo;</a></li>

                       </c:if>

               </ul>

</body>

</html>

<%@include file="../include/footer.jsp"%>

 

 

 코드로 배우는 스프링 웹 프로젝트를 보면서 따라함

반응형

'JAVA > spring' 카테고리의 다른 글

intellij error - 1  (2) 2019.09.02
[Spring] CRUD 구현  (0) 2019.08.28
paging processing(페이징 처리) - 2  (0) 2019.08.09
paging processing(페이징 처리) - 1  (0) 2019.08.08
select Implementation  (0) 2019.08.08

댓글