페이징 처리

이수보🧑🏻‍💻·2022년 2월 22일
0

기타

목록 보기
6/13

페이징 처리를 하는 방법은 정말 다양합니다.
이번 게시물이 마음에 들지 않거나 이상하다면 다른 것을 한 번 찾아보시는 것을 추천드립니다~!~!

페이징 한 번에 보기 어려운 양의 자료를 구간별로 나눈 후 출력하는 처리기법으로 일상생활에서도 흔히 접해봤을 거라고 생각합니다.


페이징의 원칙

  1. 페이징 처리는 가능한 POST 방식 보다는 GET 방식을 이용한다.
       - 사용자가 현재 무슨 페이지를 보는지 URL로 확인할 수 있게하기 위해

  1. 페이지의 수는 정말 존재하는 페이지만큼만 표시해야 한다.
       - 혼란을 방지하기 위함

  1. 이전 / 다음 버튼이 존재해야 한다.
       - 한 번에 표시할 페이지 버튼을 줄이기 위함
  1. 게시글을 조회 및 수정한 후 다시 원래의 페이지로 이동해야 한다.
       - 가끔 이게 안되있는 페이지 있는데 정말 짜증났던 경험이....
          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를 받아오게 설계하면 됩니다.

0개의 댓글