페이징 처리를 하는 방법은 정말 다양합니다.
이번 게시물이 마음에 들지 않거나 이상하다면 다른 것을 한 번 찾아보시는 것을 추천드립니다~!~!
페이징 한 번에 보기 어려운 양의 자료를 구간별로 나눈 후 출력하는 처리기법으로 일상생활에서도 흔히 접해봤을 거라고 생각합니다.
페이징의 원칙
- 페이징 처리는 가능한 POST 방식 보다는 GET 방식을 이용한다.
- 사용자가 현재 무슨 페이지를 보는지 URL로 확인할 수 있게하기 위해
- 페이지의 수는 정말 존재하는 페이지만큼만 표시해야 한다.
- 혼란을 방지하기 위함
- 꼭 이전 / 다음 버튼이 존재해야 한다.
- 한 번에 표시할 페이지 버튼을 줄이기 위함
- 게시글을 조회 및 수정한 후 다시 원래의 페이지로 이동해야 한다.
- 가끔 이게 안되있는 페이지 있는데 정말 짜증났던 경험이....
jsp의 경우 ${param.페이지번호} 로 쉽게 처리 가능
페이징 멤버변수
// 전체 글 행의 수 private int total; // 현재 페이지 번호 private int currentPage; // 전체 페이지 개수 private int totalPages; // 시작 페이지 번호 -> 이전 [1] [2] [3] [4] [5] 다음 : 일때 1 을 의미 private int startPage; // 종료 페이지 번호 -> 이전 [1] [2] [3] [4] [5] 다음 : 일때 5 를 의미 private int endPage; // 페이징의 개수 private int pagingCount; // 10페이지까지 있다면 한번에 몇개 씩 표시할 것이나 //3이라면 [이전] [1] [2] [3] [다음] 형식으로 설정 // 한 화면에 보여질 행의 개수 private int size;
페이징 공식
이 외에도 많은 공식이 존재하고 훨씬 좋은 공식도 많습니다. 본인에게 편하고 이해가 쉬운 것을 쓰시면 됩니다.
- 전체 페이지(totalPages)
total/size;보정 작업 : int는 정수형이기 때문에 13/7 의 경우 2 페이지여야 하지만 1이 나옴 때문에 ++ 작업을 추가
if(total % size > 0){ totalPages++; }
- 시작 페이지(startPage)
startPage = currentPage / pagingCount * pagingCount + 1;보정 작업 : currentPage와 pagingCount가 같은 5라고 가정시 5 /5 = 1 로 현재페이지는 5, 시작페이지는 6이 됨 때문에 -pagingCount 작업 추가
if(currentPage % pagingCount == 0){ startPage -= pagingCount; }
- 종료 페이지(startPage)
endPage = startPage + (pagingCount - 1);보정 작업 : 총 페이지의 개수가 10개라고 가정 시 startPage가 7이라면 7 + pagingCount로 인해 10을 초과한다. 때문에 =totalPages 작업을 추가
if(endPage > totalPages){ endPage = totalPages; }
공식 적용 Class
public class ArticlePage { // 전체 글 행의 수 private int total; // 현재 페이지 번호 private int currentPage; // 전체 페이지 개수 private int totalPages; // 시작 페이지 번호 -> 이전 [1] [2] [3] [4] [5] 다음 : 일때 1 을 의미 // 공식 : 현재페이지 / 페이징의 개수 * 페이징의 개수 + 1; private int startPage; // 종료 페이지 번호 -> 이전 [1] [2] [3] [4] [5] 다음 : 일때 5 를 의미 private int endPage; // 페이징의 개수 private int pagingCount; // 10페이지까지 있다면 한번에 몇개 씩 표시할 것이나 3이라면 [이전] [1] [2] [3] [다음] 형식으로 설정 // 한 화면에 보여질 행의 수 private int size; public ArticlePage(int total, int currentPage, int size, int pagingCount,List<LprodVO> content) { this.total = total; this.currentPage = currentPage; this.content = content; this.pagingCount = pagingCount; // Select 의 결과가 없다면 if(total == 0) { totalPages = 0; startPage = 0; endPage = 0; }else { // 결과가 있다면 // ----------------------------------------------------------------------------------------- // 전체 페이지 수 구하기 // 정수와 정수의 나눗셈은 결과는 정수이므로 13/7 => 1 이 된다. totalPages = total / size; if(total % size > 0) { totalPages++; } // ----------------------------------------------------------------------------------------- // 시작 페이지 구하기 // 공식 : 현재페이지 / 페이징의 개수 * 페이징의 개수 + 1; startPage = currentPage / pagingCount * pagingCount + 1; // 보정 해줘야함 ??? 현재페이지가 5일 때는 5 / 5 = 1 으로 문제가 생김 currentPage는 5인데 startPage가 6이 되어버림 if(currentPage % pagingCount == 0) { // startPage = startPage - 5(페이징의 개수); startPage -= pagingCount; } // ----------------------------------------------------------------------------------------- // 종료 페이지 구하기 endPage = startPage + (pagingCount - 1); // 보정 해줘야함 ??? startPage가 6이면 pagingCount(5)-1 = 4 == 10 이 된다. 하지만 마지막에 도달하면? 16페이지라 치면 20페이가 됨 한계초과 if(endPage > totalPages) { endPage = totalPages; } // ----------------------------------------------------------------------------------------- } } // 전체 행의 수를 리턴 public int getTotal() { return this.total; } // SELECT 의 결과가 없는가?? 체크 : true 면 없다 public boolean hasNoArticles() { return this.total == 0; } // SELECT 의 결과가 있는가?? 체크 : true 면 있다. public boolean hasArticles() { return this.total > 0; } // 현재 페이지 번호 리턴 public int getCurrentPage() { return this.currentPage; } // 전체 페이지의 개수 리턴 public int getTotalPages() { return this.totalPages; } // 목록 하단의 시작번호를 리턴 public int getStartPage() { return startPage; } // 종료 페이지 번호 리턴 public int getEndPage() { return endPage; } public int getPagingCount() { return pagingCount; } public void setTotal(int total) { this.total = total; } public void setPagingCount(int pagingCount) { this.pagingCount = pagingCount; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public void setTotalPages(int totalPages) { this.totalPages = totalPages; } public void setStartPage(int startPage) { this.startPage = startPage; } public void setEndPage(int endPage) { this.endPage = endPage; } @Override public String toString() { return "ArticlePage [total=" + total + ", currentPage=" + currentPage + ", totalPages=" + totalPages + ", startPage=" + startPage + ", endPage=" + endPage + ", content=" + content + "]"; } }
MyBatis Query
SELECT T.TEST_COL, T.TEST_COL, T.TEST_COL , T.TEST_COL, T.TEST_COL, T.TEST_COL FROM( SELECT ROW_NUMBER() OVER(ORDER BY TEST_COL) RNUM , TEST_COL , TEST_COL , TEST_COL , TEST_COL , TEST_COL FROM TEST ) T WHERE T.RNUM BETWEEN #{currentPage}*#{size}-#{size}+1 AND #{currentPage}*#{size}
Class의 생성자를 이용하여 Cotroller에 요청이 들어올 때마다 CurrentPage를 받아오게 설계하면 됩니다.