(Spring) 페이징 연습하기

DevSeoRex·2022년 6월 27일
0

Spring

목록 보기
3/3

오늘은 스프링의 정석 강의를 보면서 MyBatis를 이용한 게시판 프로젝트 중 가장 처음 접하게 되는 페이징 처리를 연습해보았다.

PageHandler 클래스를 작성해서 페이징을 콘솔로 확인할 수 있게 작성하였고, Junit4를 이용한 테스트까지 해보았다.

1. 변수 선언하기

네비게이터(웹페이지를 보면 < 1 2 3 4 5 > 와 같이 앞으로 가는 버튼과 뒤로 가는 버튼이 있고, 각 페이지 번호를 누르면 이동할 수 있게 되어 있는 것이 네비게이터이다.

해당 네비게이터에 현재 페이지를 기준으로, 첫페이지와 끝페이지가 어딘지, 또 페이지가 1이라면 뒤로 갈 공간이 없으므로 뒤로가기(Preview)가 불가능하게 처리하고, 마지막 페이지가 끝페이지와 같다면(NextView)가 불가능하게 처리하기 위해 계산에 필요한 변수들을 선언하였다.

    int totalCnt;   // 전체 데이터의 개수(게시글의 개수)
    int page;       // 현재 페이지
    int beginPage; // 시작 페이지
    int totalPage; // 전체 페이지수
    int endPage;   // 마지막 페이지
    int naviSize = 5;  // 네비게이터의 크기
    int pageSize = 5;  // 페이지의 크기
    boolean preView; // 뒤로가기
    boolean nextView; // 다음으로 가기

원래대로라면 MyBatis를 통해서 실제 데이터베이스에 접근하여 데이트의 갯수를 실제로 받아와서 페이징을 구현해야 하지만 강의 초반부에 나오는 것과 같이 데이터의 갯수는 임의로 생성자로 초기값을 설정해주고 페이징을 간단히 구현해보았다.

변수명에서 알 수 있듯이, 각각의 기능들은 주석으로 작성하였다.

2. 생성자로 값을 계산하여 초기값 주기

변수들의 값을 계산할때 필요한 필수값은 totalCnt(총 데이터의 갯수) 와 page(현재 페이지) 이다.

따라서 총 데이터의 갯수와 현재 페이지 값만 생성자로 입력받아 초기값을 지정해주고, 두 값에 따라 나머지 값들을 계산하게 하였다.

public PageHandler2(int totalCnt, int page){
        this.totalCnt = totalCnt;
        this.page = page;
        totalPage = (int)Math.ceil((double)totalCnt/pageSize);
        beginPage = (page-1)/naviSize * naviSize + 1;
        endPage = Math.min((((page-1)/naviSize + 1) * naviSize),totalPage);

        preView = beginPage != 1;
        nextView = endPage != totalPage;
    }

totalPage의 경우 총 데이터의 수를 네비게이터의 페이지 크기(한 페이지에서 표시해 줄 크기(초기값을 5로 지정했다) 나눠서 계산하면 된다. 이렇게되면 모든 변수의 값이 정수형 타입이기 때문에 총 데이터의 개수가 page크기인 5의 배수가 아닐경우 나머지 몫이 전부 버려져 문제가 생긴다.
예를 들면, 데이터가 167개라면 167/5 의 몫만 취할경우 33이 나온다 그렇다면, 33 * 5 = 165, 즉 2개의 데이터가 들어갈 곳이 없고 잘려나오게 되는 결과를 초래한다. 따라서 Math 클래스의 ceil() 메서드를 이용해서 올림 연산을 해주어, 총 페이지의 갯수를 정해야한다.

시작페이지는 page에서 1을 빼고 네비게이터의 크기로 나눠준뒤, 네비게이터의 크기를 곱하고 1을 더해주면 된다.

마지막 페이지는 page에서 1을 빼주고 네비게이터의 크기로 나눠준뒤, 1을 더하고 네비게이터의 크기를 곱해주면 된다.
여기서 totalPage보다 endPage의 값이 클 수는 없으므로,

Math클래스의 min() 메서드를 활용하여 계산한 endPage의 값보다 totalPage의 값이 적을 경우 totalPage의 값을 endPage의 값으로 사용하도록 설정하였다.

boolean형 변수인 preView와 nextView는 현재 페이지가 1페이지라면 뒤로 갈 페이지가 없으므로, preView를 보여주지 않고,
현재 페이지를 기점으로 마지막 페이지가 끝페이지(가장 마지막 페이지)와 같다면, 앞으로 갈 페이지가 없으므로, NextView를 표시하지 않게 작성하였다.

3. 출력

public void print(){
        System.out.print(preView ? "[Preview] " : "");
        for(int i=beginPage; i<=endPage; i++){
            System.out.print(i + " ");
        }
        System.out.print(nextView ? "[nextView]" : "");
    }

preView의 값이 참일때만 preView를 출력하게 하고,
바로 아래줄에서는 beginPage 부터 endPage까지 반복해서 출력되게 하였다.
마지막으로 nextView가 참일때만 nextView를 출력되게 하였다.

4. Test 코드

총 데이터의 갯수와 현재 페이지수를 다양하게 설정(데이터의 갯수가 5로 나눠 떨어지거나, 나누어 떨어지지 않는 케이스 모두 설정)하여 3번 테스트를 수행하였다.

public class PageHandler2Test {

    @Test
    public void test1() {
        PageHandler2 pageHandler2 = new PageHandler2(167,32);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==31);
        assertTrue(pageHandler2.endPage==34);
    }

    @Test
    public void test2() {
        PageHandler2 pageHandler2 = new PageHandler2(180,23);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==21);
        assertTrue(pageHandler2.endPage==25);
    }

    @Test
    public void test3() {
        PageHandler2 pageHandler2 = new PageHandler2(210,40);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==36);
        assertTrue(pageHandler2.endPage==40);
    }
}

test1의 경우, 현재 페이지가 32 페이지이므로, 총 34페이지 중 전 단락이 26~30 까지가 끝났으므로 시작 페이지는 31이고 끝 페이지가 34가 되면 테스트 통과조건이기때문에 assertTrue() 메서드의 조건을 시작페이지가 31페이지이고, 끝 페이지가 34페이지일것을 지정하였다.

test2,test3도 마찬가지로 똑같이 작성하였다.

출력은 정확하게 잘 된다.

전체 코드

PageHandler2.java

public class PageHandler2 {
    int totalCnt;   // 전체 데이터의 개수(게시글의 개수)
    int page;       // 현재 페이지
    int beginPage; // 시작 페이지
    int totalPage; // 전체 페이지수
    int endPage;   // 마지막 페이지
    int naviSize = 5;  // 네비게이터의 크기
    int pageSize = 5;  // 페이지의 크기
    boolean preView; // 뒤로가기
    boolean nextView; // 다음으로 가기

    public PageHandler2(int totalCnt, int page){
        this.totalCnt = totalCnt;
        this.page = page;
        totalPage = (int)Math.ceil((double)totalCnt/pageSize);
        beginPage = (page-1)/naviSize * naviSize + 1;
        endPage = Math.min((((page-1)/naviSize + 1) * naviSize),totalPage);

        preView = beginPage != 1;
        nextView = endPage != totalPage;
    }

    public void print(){
        System.out.print(preView ? "[Preview] " : "");
        for(int i=beginPage; i<=endPage; i++){
            System.out.print(i + " ");
        }
        System.out.print(nextView ? "[nextView]" : "");
    }

    @Override
    public String toString() {
        return "PageHandler2{" +
                "totalCnt=" + totalCnt +
                ", page=" + page +
                ", beginPage=" + beginPage +
                ", totalPage=" + totalPage +
                ", endPage=" + endPage +
                ", naviSize=" + naviSize +
                ", pageSize=" + pageSize +
                ", preView=" + preView +
                ", nextView=" + nextView +
                '}';
    }
}

PageHandler2Test.java

import org.junit.Test;

import static org.junit.Assert.*;

public class PageHandler2Test {

    @Test
    public void test1() {
        PageHandler2 pageHandler2 = new PageHandler2(167,32);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==31);
        assertTrue(pageHandler2.endPage==34);
    }

    @Test
    public void test2() {
        PageHandler2 pageHandler2 = new PageHandler2(180,23);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==21);
        assertTrue(pageHandler2.endPage==25);
    }

    @Test
    public void test3() {
        PageHandler2 pageHandler2 = new PageHandler2(210,40);
        pageHandler2.print();
        System.out.println();
        System.out.println(pageHandler2.toString());
        assertTrue(pageHandler2.beginPage==36);
        assertTrue(pageHandler2.endPage==40);
    }
}

출처 : 스프링의 정석 남궁성과 끝까지 간다(패스트 캠퍼스)

0개의 댓글