출처 : http://dualist.tistory.com/147
매번 페이징을 구현할 때마다, 한 두시간 씩 끙끙대는 것 같다.
생각을 의사코드로 적은 후에 그걸 코드화 하는 습관을 들여야하는데,
성질이 급해서 일단 생각을 코드화 해서 버그를 잡은 다음에.. 그제서야 의사코드로 적고 있다.
다음은 생각의 흐름를 정리해본 것이다.
************************************************************************************************
총 데이터 수가 37개인 데이터를 페이징 처리 해보자.
데이터는 DB에서 가져오거나 xml파일을 읽어올 것이다.
페이지를 3 페이지씩 보여줄 수도 있고 [1] [2] [3] [다음]
혹은 10페이지씩 보여줄 수도 있다. [1] [2] [3] [4] [5] ...[10] [다음]
값 셋팅에 따라 달라질 수 있도록 페이지그룹 사이즈(pageGroupSize) 변수를 사용하겠다.
셋팅할 수 있는 값이 페이지그룹 사이즈 말고 또 무엇이 있을까?
한 페이지 당 보여주는 리스트 갯수도 변할 가능성이 많다.
이것은 페이지 사이즈(pageSize) 변수로 놓자.
그러면, 페이징 로직의 결과를 예측하기 위해서 이 두개의 변수에 값을 넣어보자.
총 데이터 갯수 (count): 37
페이지그룹 사이즈 (페이지그룹을 몇개씩 묶을 것인가) : 3
페이지 사이즈 (한 페이지 당 리스트 갯수): 4
이렇게 셋팅을 할 경우, 나오는 결과는?
총 페이지 수(pageCount)는 37 / 4 = 9.25 니까 10 페이지 되겠다.
pageCount = (count / pageSize ) + ( count % pageSize == 0 ? 0 : 1);
=> count % pageSize == 0 ? 0 : 1 이 수식을 풀어서 쓰면
if(count % pageSize == 0)
return 0;
else
return 1;
이렇게 표현된다.
=============================================================================
[1][2][3] [4][5][6] [7][8][9] [10]
페이지그룹넘버(numPageGroup) : - 1 - - 2 - - 3 - - 4 -
=============================================================================
페이지 그룹은 위와같이 총 4개로 나올 것이다. (pageGroupCount : 4)
이 페이지 그룹을 본 후, 현재페이지가 호출될 경우를 생각해보면
5페이지가 호출된다면 numPageGroup이 2인 상태로 페이지바가 보여질 것이다.
그렇다면, 호출된 현재페이지를 가지고 페이지그룹넘버를 구하고,
페이지그룹넘버값으로 페이지바의 첫번째 페이지를 계산해보자.
numPageGroup = 올림(currentPage/pageGroupSize)
=> int numPageGroup = (int) Meth.ceil ((double)currentPage/pageGroupSize)
=> numPageGroup : 올림(5/3) = 2
startPage = (numPageGroup - 1)*pageGroupSize + 1;
=> stratPage : (2-1)*3+1 = 4
이제 시작페이지를 가지고 마지막 페이지도 구해보자
endPage = startPage + pageGroupSize -1 => 4+3-1 = 6
이런식으로 시작페이지와 마지막페이지를 구했다면, for문을 돌려서 페이지바를 출력할 수 있을 것이다.
그런데, 마지막 페이지그룹을 위 공식대로 계산하면 endPage가 12페이지가 나온다.
총 페이지수가 10개인데 12페이지까지 출력되면 안 될것이다.
따라서, if문 처리를 추가해주자.
if( 마지막페이지 > 총페이지 )
마지막페이지 = 총 페이지 => endPage = 10
************************************************************************************************
로직은 자바 클래스로, 출력부분은 JSTL 코드로 작성했는데.. 페이징 부분 코드는 다음과 같다.
[ 자바 클래스 ]
//한 페이지 당 보여줄 글 갯수
17: private final static int pageSize = 4;
18: //페이지그룹안의 페이지 갯수 ex) [이전] 1 2 3 4 5 [다음] 일 경우 페이지 갯수는 5
19: private final static int pageGroupSize = 3;
String pageNum = request.getParameter("pageNum");//페이지 번호
25:
26: if (pageNum == null) {
27: pageNum = "1";
28: }
29:
30: int currentPage = Integer.parseInt(pageNum);
31: int startRow = (currentPage - 1) * pageSize + 1;//한 페이지의 시작글 번호
32: int endRow = currentPage * pageSize;//한 페이지의 마지막 글번호
33: int count = 0;
34: int number=0;
35: ArrayList articleList = new ArrayList();
36: BoardDAO dbPro = BoardDAO.getInstance();//DB연동
37: count = dbPro.getTotalCnt();//전체 글의 수
38:
39: if (count > 0) {
40: if(endRow>count)
41: endRow = count;
42: articleList = dbPro.select(startRow,endRow);//현재 페이지에 해당하는 글 목록
43:
44: } else {
45: articleList = null;
46: }
47:
48: number=count-(currentPage-1)*pageSize;//글목록에 표시할 글번호
49:
50: //페이지그룹의 갯수
51: //ex) pageGroupSize가 3일 경우 '[1][2][3]'가 pageGroupCount 개 만큼 있다.
52: int pageGroupCount = count/(pageSize*pageGroupSize)+( count % (pageSize*pageGroupSize)== 0 ? 0 : 1);
53: //페이지 그룹 번호
54: //ex) pageGroupSize가 3일 경우 '[1][2][3]'의 페이지그룹번호는 1 이고 '[2][3][4]'의 페이지그룹번호는 2 이다.
55: int numPageGroup = (int) Math.ceil((double)currentPage/pageGroupSize);
//해당 뷰에서 사용할 속성
57: request.setAttribute("currentPage", new Integer(currentPage));
58: request.setAttribute("startRow", new Integer(startRow));
59: request.setAttribute("endRow", new Integer(endRow));
60: request.setAttribute("count", new Integer(count));
61: request.setAttribute("pageSize", new Integer(pageSize));
request.setAttribute("number", new Integer(number));
63: request.setAttribute("pageGroupSize", new Integer(pageGroupSize));
64: request.setAttribute("numPageGroup", new Integer(numPageGroup));
65: request.setAttribute("pageGroupCount", new Integer(pageGroupCount));
66: request.setAttribute("articleList", articleList);
67:
68: return "./list.jsp";//해당 뷰
[ JSP 부분 ]
<c:if test="${count > 0}">
<c:set var="pageCount" value="${count / pageSize + ( count % pageSize == 0 ? 0 : 1)}"/>
<c:set var="startPage" value="${pageGroupSize*(numPageGroup-1)+1}"/>
<c:set var="endPage" value="${startPage + pageGroupSize-1}"/>
<c:if test="${endPage > pageCount}" >
<c:set var="endPage" value="${pageCount}" />
</c:if>
<c:if test="${numPageGroup > 1}">
<a href="./list.do?pageNum=${(numPageGroup-2)*pageGroupSize+1 }">[이전]</a>
</c:if>
<c:forEach var="i" begin="${startPage}" end="${endPage}">
<a href="list.do?pageNum=${i}">[
<font color="#000000" />
<c:if test="${currentPage == i}">
<font color="#bbbbbb" />
</c:if>
${i}
</font>]
</a>
</c:forEach>
<c:if test="${numPageGroup < pageGroupCount}">
<a href="./list.do?pageNum=${numPageGroup*pageGroupSize+1}">[다음]</a>
</c:if>
</c:if>
페이지그룹 사이즈 (페이지그룹을 몇개씩 묶을 것인가) : 3
페이지 사이즈 (한 페이지 당 리스트 갯수): 4
이렇게 셋팅을 할 경우, 나오는 결과는?
총 페이지 수(pageCount)는 37 / 4 = 9.25 니까 10 페이지 되겠다.
pageCount = (count / pageSize ) + ( count % pageSize == 0 ? 0 : 1);
=> count % pageSize == 0 ? 0 : 1 이 수식을 풀어서 쓰면
if(count % pageSize == 0)
return 0;
else
return 1;
이렇게 표현된다.
=============================================================================
[1][2][3] [4][5][6] [7][8][9] [10]
페이지그룹넘버(numPageGroup) : - 1 - - 2 - - 3 - - 4 -
=============================================================================
페이지 그룹은 위와같이 총 4개로 나올 것이다. (pageGroupCount : 4)
이 페이지 그룹을 본 후, 현재페이지가 호출될 경우를 생각해보면
5페이지가 호출된다면 numPageGroup이 2인 상태로 페이지바가 보여질 것이다.
그렇다면, 호출된 현재페이지를 가지고 페이지그룹넘버를 구하고,
페이지그룹넘버값으로 페이지바의 첫번째 페이지를 계산해보자.
numPageGroup = 올림(currentPage/pageGroupSize)
=> int numPageGroup = (int) Meth.ceil ((double)currentPage/pageGroupSize)
=> numPageGroup : 올림(5/3) = 2
startPage = (numPageGroup - 1)*pageGroupSize + 1;
=> stratPage : (2-1)*3+1 = 4
이제 시작페이지를 가지고 마지막 페이지도 구해보자
endPage = startPage + pageGroupSize -1 => 4+3-1 = 6
이런식으로 시작페이지와 마지막페이지를 구했다면, for문을 돌려서 페이지바를 출력할 수 있을 것이다.
그런데, 마지막 페이지그룹을 위 공식대로 계산하면 endPage가 12페이지가 나온다.
총 페이지수가 10개인데 12페이지까지 출력되면 안 될것이다.
따라서, if문 처리를 추가해주자.
if( 마지막페이지 > 총페이지 )
마지막페이지 = 총 페이지 => endPage = 10
************************************************************************************************
로직은 자바 클래스로, 출력부분은 JSTL 코드로 작성했는데.. 페이징 부분 코드는 다음과 같다.
[ 자바 클래스 ]
//한 페이지 당 보여줄 글 갯수
17: private final static int pageSize = 4;
18: //페이지그룹안의 페이지 갯수 ex) [이전] 1 2 3 4 5 [다음] 일 경우 페이지 갯수는 5
19: private final static int pageGroupSize = 3;
String pageNum = request.getParameter("pageNum");//페이지 번호
25:
26: if (pageNum == null) {
27: pageNum = "1";
28: }
29:
30: int currentPage = Integer.parseInt(pageNum);
31: int startRow = (currentPage - 1) * pageSize + 1;//한 페이지의 시작글 번호
32: int endRow = currentPage * pageSize;//한 페이지의 마지막 글번호
33: int count = 0;
34: int number=0;
35: ArrayList articleList = new ArrayList();
36: BoardDAO dbPro = BoardDAO.getInstance();//DB연동
37: count = dbPro.getTotalCnt();//전체 글의 수
38:
39: if (count > 0) {
40: if(endRow>count)
41: endRow = count;
42: articleList = dbPro.select(startRow,endRow);//현재 페이지에 해당하는 글 목록
43:
44: } else {
45: articleList = null;
46: }
47:
48: number=count-(currentPage-1)*pageSize;//글목록에 표시할 글번호
49:
50: //페이지그룹의 갯수
51: //ex) pageGroupSize가 3일 경우 '[1][2][3]'가 pageGroupCount 개 만큼 있다.
52: int pageGroupCount = count/(pageSize*pageGroupSize)+( count % (pageSize*pageGroupSize)== 0 ? 0 : 1);
53: //페이지 그룹 번호
54: //ex) pageGroupSize가 3일 경우 '[1][2][3]'의 페이지그룹번호는 1 이고 '[2][3][4]'의 페이지그룹번호는 2 이다.
55: int numPageGroup = (int) Math.ceil((double)currentPage/pageGroupSize);
//해당 뷰에서 사용할 속성
57: request.setAttribute("currentPage", new Integer(currentPage));
58: request.setAttribute("startRow", new Integer(startRow));
59: request.setAttribute("endRow", new Integer(endRow));
60: request.setAttribute("count", new Integer(count));
61: request.setAttribute("pageSize", new Integer(pageSize));
request.setAttribute("number", new Integer(number));
63: request.setAttribute("pageGroupSize", new Integer(pageGroupSize));
64: request.setAttribute("numPageGroup", new Integer(numPageGroup));
65: request.setAttribute("pageGroupCount", new Integer(pageGroupCount));
66: request.setAttribute("articleList", articleList);
67:
68: return "./list.jsp";//해당 뷰
[ JSP 부분 ]
<c:set var="pageCount" value="${count / pageSize + ( count % pageSize == 0 ? 0 : 1)}"/>
<c:set var="startPage" value="${pageGroupSize*(numPageGroup-1)+1}"/>
<c:set var="endPage" value="${startPage + pageGroupSize-1}"/>
<c:if test="${endPage > pageCount}" >
<c:set var="endPage" value="${pageCount}" />
</c:if>
<c:if test="${numPageGroup > 1}">
<a href="./list.do?pageNum=${(numPageGroup-2)*pageGroupSize+1 }">[이전]</a>
</c:if>
<c:forEach var="i" begin="${startPage}" end="${endPage}">
<a href="list.do?pageNum=${i}">[
<font color="#000000" />
<c:if test="${currentPage == i}">
<font color="#bbbbbb" />
</c:if>
${i}
</font>]
</a>
</c:forEach>
<c:if test="${numPageGroup < pageGroupCount}">
<a href="./list.do?pageNum=${numPageGroup*pageGroupSize+1}">[다음]</a>
</c:if>
</c:if>