Paging Algorithum

채상혁·2022년 2월 14일
0

Algorithum

목록 보기
1/2

페이지 알고리즘

게시판을 생성할 때 DB에서 데이터를 가지고와서 뿌린다. 이러한 데이터가 여러개
일 경우 한 페이지 안에 많은 양의 데이터가 존재하게 되는데 그러한 점을 페이지를
나누어 볼 수 있게 해주는 알고리즘이다.

페이징 알고리즘 만들기

1. 사용자가 보게 될 페이지 화면

  • 한 화면에 페이지 버튼을 10개씩 배치해서 보여준다면?
    ex) 1 2 3 4 .... 9 10 [다음] // [이전] 31 32 33 34 .... 39 40 [다음]

  • 만약에 총 게시물의 수가 67개라면?
    한 페이지에 게시물이 10개씩 들어간다면?
    1 2 3 4 5 6 7

  • 총 게시물의 수가 142개이고, 현재 사용자가 12페이지를 클릭했다면?
    [이전] 11 12 13 14 15

2. 우선 총 게시물의 개수를 조회해야 합니다.

  • 총 게시물 수는 DB로부터 수를 조회하는 SQL문을 작성합니다.

3. 사용자가 현재 위치한 페이지를 기준으로

끝 페이지 번호를 계산하는 로직을 작성.

  • 만약 현재 사용자가 보고 있는 페이지가 3페이지이고,
    한 화면에 보여줄 페이지 버튼이 10개라면?
    -> 끝 페이지 번호: 10번
  • 만약 현재 페이지가 36페이지고, 한 화면에 보여줄 페이지 수가
    20개라면?
    -> 끝 페이지 번호: 40번

공식: Math.ceil(현재 위치한 페이지 번호 / 한 화면당 보여질 페이지 수)
* 한 화면당 보여질 페이지 수

4. 시작 페이지 번호 계산

  • 현재 위치한 페이지가 15페이지이고, 한 화면에 보여줄 페이지 버튼이
    10 개라면?
    -> 시작페이지 번호: 11번

  • 현재 위치한 페이지가 73페이지이고, 한 화면에 버튼 20개씩 보여준다면?
    -> 시작 페이지 번호: 61번

공식: (끝 페이지 번호 - 한 화면에 보여질 페이지 버튼 수) + 1

5. 끝 페이지를 보정

  • 총 게시물 수가 324개이고, 한 페이지당 10개의 게시물을 보여준다.
  • 그리고 이 사람은 현재 31페이지를 보고 있다.
  • 그리고, 한 화면에 페이지 버튼은 10개가 배치된다.
  • 그렇다면, 위 공식에 의한 끝 페이지는 몇 번으로 계산되는가? -> 40번
  • 하지만 실제 끝 페이지는 몇 번이면 충분한가? -> 33번

5-1. 이전 버튼 활성화 여부 설정

  • 시작 페이지가 1로 구해진 시점에서는 비활성, 나머지는 활성화.

5-2. 다음 버튼 활성화 여부 설정

  • 공식: 보정 전 끝 페이지 번호 x 한 페이지에 들어갈 게시물 수 >= 총 게시물 수
    -> 비활성

5-3. 끝 페이지 값 보정

  • 다음 버튼이 비활성화 되었다면 총 게시물 수에 맞춰 끝 페이지 번호를
    재 보정합니다.
    공식: Math.ceil(총 게시물의 개수 / 한 페이지에 보여줄 게시물 수)

페이지에 정보를 담고있는 PageVO 생성

@Getter
@Setter
public class PageVO {

	private int pageNum;
	private int countPerPage;
	
	//검색에 필요한 데이터를 변수로 선언.
	private String keyword;
	private String condition;
	
	public PageVO() {
		this.pageNum = 1;
		this.countPerPage = 10;
	}
}

   getter 와 setter는 lombok으로 구현해 주었다.

페이징을 처리할 PageCreator(pageCriteria)를 생성.

@Getter
@Setter
@ToString
public class PageCreator {


	   private PageVO paging;
	   private int articleTotalCount;
	   private int endPage;
	   private int beginPage;
	   private boolean prev;
	   private boolean next;
	   
	   private final int buttonNum = 5;
	   
	   
	   private void calcDataOfPage() {
	      
	      endPage = (int) (Math.ceil(paging.getPageNum() / (double) buttonNum) * buttonNum);
	      
	      beginPage = (endPage - buttonNum) + 1;
	      
	      prev = (beginPage == 1) ? false : true;
	      
	      next = articleTotalCount <= (endPage * paging.getCountPerPage()) ? false : true;
	      
	      if(!next) {
	         endPage = (int) Math.ceil(articleTotalCount / (double) paging.getCountPerPage()); 
	      }
	      
	   }
	   
	   //컨트롤러가 총 게시물의 개수를 PageCreator에게 전달한 직후에 
	   //바로 페이징 버튼 알고리즘이 돌아갈 수 있도록 setter를 커스텀.
	   public void setArticleTotalCount(int articleTotalCount) {
	      this.articleTotalCount = articleTotalCount;
	      calcDataOfPage();
	   }
	
}

예시 sql 페이징 처리.

 	<select id="getList" resultMap="ReplyMap">
  	SELECT * FROM
  	 (
	  	 SELECT ROWNUM AS rn, tbl.* FROM 
		  	(
		  	SELECT * FROM freereply
		  	WHERE bno = #{bno}
		  	ORDER BY rno DESC
		  	) tbl
  	 )
  	 <![CDATA[
		WHERE rn > (#{paging.pageNum} - 1) * #{paging.countPerPage}
  		AND rn <= #{paging.pageNum} * #{paging.countPerPage}	  	 
  	 ]]> 
  	</select>
    <!-- < > 연산자를 인식하기 떄문에 <![CDATA[]]>를 사용하여 처리해줍니다. --!>

0개의 댓글