@Test
public void paging() {
//given
for(int i = 1; i <= 100; i++) {
memberJpaRepository.save(new Member("member"+i, 10));
}
int pageNum = 10; //51~60
int pageSize = 10;
long totalCount = memberJpaRepository.findAll().size();
int totalPage = (int) Math.ceil(totalCount / pageSize);
int blockPage = 5; //블록당 페이지 수
int startPage = ((pageNum-1)/blockPage)*blockPage+1;
int tempEndPage = (((pageNum-1)/blockPage)+1)*blockPage;
int endPage = (tempEndPage <= totalPage) ? tempEndPage : totalPage;
int start = (pageNum-1)*pageSize+1;
int tempEnd = pageNum*pageSize;
int end = (tempEnd) <= totalCount ? tempEnd : (int)totalCount;
int offset = start;
int limit = end;
for (int i = start; i <= end; i++) {
System.out.println(i);
}
for (int i = startPage; i <= endPage; i++) {
String page = String.valueOf(i);
if(i==pageNum) page ="["+page+"]";
if(i==endPage) System.out.println(page);
else System.out.print(page+", ");
}
}
페이징 코드를 연습해보았다. 효율적인 코드가 아닐 수 있다.
먼저 게시물의 수는 100개로 만들었다.
원하는 출력은 다음과 같다.
61
62
63
64
65
66
67
68
69
70
6, [7], 8, 9, 10
✔ 먼저 페이지에 몇개의 게시물이 나올지 정했다.
int pageSize = 10;
✔ 게시물의 총 개수를 구했다.
long totalCount = memberJpaRepository.findAll().size();
✔ 페이지의 총 개수를 구했다.
int totalPage = (int) Math.ceil(totalCount / pageSize);
-> 예를 들어 게시물이 총 134개라고 생각해보자.
페이지당 게시물이 10개씩 출력한다고 가정했을때
게시물이 134개면 총 13페이지가 나와야한다.
1 : 1~10,
2 : 11~20,
3 : 21~30,
4 : 31~40,
5 : 41~50,
6 : 51~60,
7 : 61~70,
8 : 71~80,
9 : 81~90,
10 : 91~100,
11 : 101~110,
12 : 111~120,
13 : 121~130,
14 : 131~134
따라서 총 게시물/에서 페이지 사이즈를 나누고 소수점을 올리는 공식이 만들어진것이다.
예를들어 134를 봤을때
134/10 = 13.4가 나온다. 하지만 14페이지가 나와야하기때문에 맞지않는다. 맞으려면 소수점을 올려줘야한다.
간단하게 생각하면 된다. 134개의 문서를 바구니에 담아야하는데 바구니에는 최대 문서가 10개 밖에 안들어간다.
그렇다면 바구니가 몇개 필요할까? 당연히 14개 필요하다. 13개는 꽉찬 바구니, 1개는 4개만 들어있는 바구니
이런식으로 생각하면 왜 소수점을 올리는 지 이해할 수 있을 것이다.
✔ 블록당 페이지수를 5로 지정했다.
int blockPage = 5
블록당 페이지 수란 한 블록에 몇개의 페이지를 출력할 것인지 정하는거다.
예를들어 블록당 페이지수가 5일때
1,2,3,4,5
6,7,8,9,10
해당 숫자들이 출력된다.
✔블록에서 시작 페이지를 구하는 공식이다.
//int startPage = (pageNum/blockPage)*blockPage+1;
int startPage = ((pageNum-1)/blockPage)*blockPage+1;
처음에는 첫번째 코드가 맞는줄 알았다. 잘 못된 코드였다.
주의 해야할게 페이징 처럼 1~10 ,11~20 이런식으로 값이 나와야 하는경우에는
반드시 경계값 테스트를 해야한다.
1과 10 그리고 중간 값 5를 넣어봐서
1,2,3,4,5,6,7,8,9,10으로 블록에서 잘 출력되는지 확인해야한다.
startPage는 예를들어 블록당 페이지가 5개씩 출력된다고 치고 페이지가 8일때
startPage가 6이여야한다.
6을넣어도 6, 7을 넣어도 6, 8을 넣어도 6, 9를 넣어도 6, 10을 넣어도 6이 나와야한다는거다.
7을 넣었을때 6이 나오게 하려면 어떻게 해야할까
6은 (1*5)+1이다. 1*5를 한 이유는 블록당 페이지가 5이기 때문이다.
7은((1*5)+1)+1이다. 이것을 6으로 어떻게 만들까
8은(((1*5)+1)+1)+1이다. 이것을 6으로 어떻게 만들까
즉 +1을 제외한 나머지를 5로 만들어야한다.
6/5 =1이다 (int는 정수만 출력하기때문에)
(6/5)*5는 5이다. (6/5)*5+1은 6이다.
7/5 =1이다 (int는 정수만 출력하기때문에)
(7/5)*5는 5이다. (7/5)*5+1은 6이다.
여기까지 보면 (pageNum/blockPage)*blockPage+1이 정답으로 보인다.
하지만
page가 10일때 문제가된다.
page가 10이면 아래와 같이 출력이 되야함으로 startPage가 6이나와야한다.
6,7,8,9,10
하지만 (10/5)*5+1 =10이 나오고만다. 6이 아닌것이다.
따라서 pageNum에 1을 빼주면 문제가 해결된다.
(6-1)/5 =1이다 (int는 정수만 출력하기때문에)
((6-1)/5)*5는 5이다. ((6-1)/5)*5+1은 6이다.
(7-1)/5 =1이다 (int는 정수만 출력하기때문에)
((7-1)/5)*5는 5이다. ((7-1)/5)*5+1은 6이다.
((10-1)/5)*5+1 =6
즉 블록의 시작페이지 코드는 다음과 같다.
int startPage = ((pageNum-1)/blockPage)*blockPage+1;
✔블록의 마지막 페이지는 다음과 같다.(while문으로 작성할경우 필요하지않다.)
//int tempEndPage = (((pageNum)/blockPage)+1)*blockPage;
int tempEndPage = (((pageNum-1)/blockPage)+1)*blockPage;
int endPage = (tempEndPage <= totalPage) ? tempEndPage : totalPage;
이부분도 경계값 테스트를 안해서 잘못 생각했었다.
위와 마찬가지로 블록당 페이지수 5라고 생각했을때
6페이지면
6/5 =1이다 (int는 정수만 출력하기때문에)
(6/5)는 1이고 (6/5)+1=2이다 . 따라서 ((6/5)+1)*5는 10이다.
7페이지면
6/5 =1이다 (int는 정수만 출력하기때문에)
(7/5)는 1이고 (7/5)+1=2이다 . 따라서 ((7/5)+1)*5는 10이다.
8페이지면
8/5 =1이다 (int는 정수만 출력하기때문에)
(8/5)는 1이고 (8/5)+1=2이다 . 따라서 ((8/5)+1)*5는 10이다.
하지만 10페이지일때 문제가 생긴다.
10/5 =2이다 (int는 정수만 출력하기때문에)
(10/5)는 2이고 (10/5)+1=3이다 . 따라서 ((10/5)+1)*5는 15이다.
10페이지일때도 당연히
6,7,8,9,10을 출력해야하기때문에 블록의 endPage는 10이 출력되야 맞지만 15가 출력되고 말았다.
이를 수정하기위해 -1을 해줘야한다.
6페이지면
6/5 =1이다 (int는 정수만 출력하기때문에)
((6-1)/5)는 1이고 ((6-1)/5)+1=2이다 . 따라서 (((6-1)/5)+1)*5는 10이다.
7페이지면
(7-1)/5 =1이다 (int는 정수만 출력하기때문에)
((7-1)/5)는 1이고 ((7-1)/5)+1=2이다 . 따라서 (((7-1)/5)+1)*5는 10이다.
8페이지면
(8-1)/5 =1이다 (int는 정수만 출력하기때문에)
((8-1)/5)는 1이고 ((8-1)/5)+1=2이다 . 따라서 (((8-1)/5)+1)*5는 10이다.
하지만 10페이지일때 문제가 생긴다.
(10-1)/5 =1이다 (int는 정수만 출력하기때문에)
((10-1)/5)는 1이고 ((10-1)/5)+1=2이다 . 따라서 (((10-1)/5)+1)*5는 10이다.
따라서 아래의 코드가 나오는 것이다.
int tempEndPage = (((pageNum-1)/blockPage)+1)*blockPage;
while문의 경우에는 endPage가 필요하지 않다. 왜냐하면 한 블록에 5개의 페이지를 출력한다고 가정했을때
blocount가 5에 도달하면 종료하게 하면 되기 때문이다.
아래의 코드가 그렇다.
blockCount<=blockPage
예를들어 블록에 5개의 페이지를 출력하면 1,2,3,4,5
5개를 count를 세고 넘으면 종료해버리는거다. 1,2,3,4,5페이지를 출력한다는게 아니라 1,2,3,4,5 카운터를 세는거다.
startPage가 6이면 6,7,8,9,10이 출력되는 동안 blockCount는 1,2,3,4,5를 카운트하게되고 5에 도달하면 while문을 종료시킨다.
또한 총페이지가 13이라고 치면
11, 12, 13으로 출력되고 while문을 종료시켜야한다.
하지만 blockCount가 5이기때문에 11,12,13,14,15 까지 출력하려고 할것이다.
이를 막기위해 아래의 코드가 존재한다. 출력하는 페이지가 총페이지 수를 못넘게 방지한다.
11, 12, 13까지 출력하다가 14로 넘어가려는 순간 totalPage는 13이기때문에 while문이 중지되는 것이다.
pageTemp <= totalPages
이게 좀 복잡하다고 생각이들면 위와 같이 endpage를 구하고 for문으로 돌려도 된다.
int tempEndPage = (((pageNum-1)/blockPage)+1)*blockPage;
예를 들어 총페이지수가 13이다. 하지만 blockPage가 5이면 11,12,13,14,15로 출력하려하기때문에
tempEndPage는 15가 될것이다 이를 방지하기위해 tempEndpage <=totalPage일때만 tempEndpage를 블록의 마지막값으로 쓰고 아닐 경우에는 totalPage를 블록의 마지막 값으로 쓴다.
전체 페이지수가 13이면 11 12 13까지만 해야하니 블록의 마지막 값을 13으로 하라는 뜻이다.
int endPage = (tempEndPage <= totalPage) ? tempEndPage : totalPage;
for (int i = startPage; i <= endPage; i++) {
String page = String.valueOf(i);
if(i==pageNum) page ="["+page+"]";
if(i==endPage) System.out.println(page);
else System.out.print(page+", ");
}
✔ 한 페이지에 출력되는 게시물들의 수를 구하는 식이다.
int start = (pageNum-1)*pageSize+1;
int tempEnd = pageNum*pageSize;
int end = (tempEnd) <= totalCount ? tempEnd : (int)totalCount;
한 페이지의 게시물수가 10개라고 가정할때
1페이지면 1~10임으로 첫페이지의 시작은 1이 나와야한다
2페이지면 11~20임으로 첫페이지의 시작은 11이 나와야한다.
따라서 1*10 = 1이나와야하고
2*10=2가 나와야한다.
즉 페이지에 1을 빼본다.
(1-1)*10=0
(2-1)*10=10
원했던 값에 1이 부족하다.
(1-1)*10+1=1
(2-1)*10+1=11
1페이지면 1~10임으로 첫페이지의 끝은 10이 나와야한다
2페이지면 11~20임으로 첫페이지의 끝은 20이 나와야한다.
end는 해당페이지 X 게시물수하면된다.
end는 마찬가지로 총 게시물수를 넘으면 안되기때문에
해당경우를 방지하는 삼항연산자를 넣었다.
✔ 출력해본다.
for (int i = start; i <= end; i++) {
System.out.println(i);
}
for (int i = startPage; i <= endPage; i++) {
String page = String.valueOf(i);
if(i==pageNum) page ="["+page+"]";
if(i==endPage) System.out.println(page);
else System.out.print(page+", ");
}
91
92
93
94
95
96
97
98
99
100
6, 7, 8, 9, [10]