과거 제가 개발 기초를 배울 때 나름 정리를 해두었던건데 이곳에 다시 제대로 정리를 해봅니다.
처음 실무를 접하며 가장 기본 중 하나가 페이징 처리라고 생각합니다. (아... 아닌가? ㅋㅋ) 원리를 이야기해서 어떤 언어든, 환경이든 익혀서 사용했으면 합니다. 아시는분도 다 까먹으셨을테니 오랜만에 다시 보시면 리마인드 되실겁니다. ㅋㅋㅋ
'그까이꺼 대충 페이징 유틸, 라이브러리 갖다 쓰면 돼'라고 생각할수도 있겠지만 환경이 항상 가져다 쓸수 있는건 아니니까요.
페이징 처리의 원리
먼저 두가지만 정리하고 가면 됩니다.
1. 페이징을 하기 위해서는 한 화면에 몇개의 글을 보여줄 것인가?
2. 총 몇개의 페이지를 보여 줄 것인가?
의 선 조건이 있어야겠죠.
그렇다면 페이징 클래스는 몇개의 글을 보여줄 것인가를 위한 w_size 라는 멤버 변수를 둬보죠.
5개씩 보여줍시다. 계산은 어떻게 할까요?
w_size = 5;
[페이지수 구하기]
글이 42개가 있다고 한다면
(42 - 1 / w_size ) + 1 = 9페이지
40개로 바꾸어봅시다.
(40 - 1 / 5 ) + 1 = 8
딱 나누어 떨어지는 40으로 해도 8 이 맞게 나오는군요.
그렇다면 페이지 카운트 식은 이렇겠네요.
( 글 갯수 - 1 / w_size ) + 1
[페이지번호 구하기]
그 다음 구해야 할것은 뭐가 있을까요? 아. 페이징 수가 나왔으니 페이징 사이즈에 따라 다시 시작 페이지를 보여줘야 겠지요. 보통 페이징 화면이
pre 1.2.3.4.5 next
이런식으로 뿌려지죠.
여기서 1과 5, 페이징의 시작과 끝을 구해야 겠죠? 시작 페이지는 현재 보고 있는
( (페이지 번호 -1) / 총 페이지 사이즈 ) * 총 페이지 사이즈 + 1
로 구할수 있습니다. Default 페이지 번호는 1로 되겠죠?
( ( 1 -1 ) / 5 ) * 5 + 1 = 1
만약 7 페이지를 보고 있다고 하고 7을 넣어봅시다.
( ( 7 -1 ) / 5 ) * 5 + 1 = 6
이런식으로 첫 시작 페이지 번호를 구할수 있습니다. 그럼 마지막 번호는 어떻게 구할까요?
시작 페이지 번호 + 페이지 총 사이즈 -1
1 + 5 - 1 = 5
시작 페이지 번호를 6으로 바꿔볼까요?
6 + 5 - 1 = 10 이 나오는군요.. 맞죠?
하지만 여기서 총 페이지 숫자는 9입니다. 9가 마지막 페이지인데 10이 나올수가 없죠??
따라서 다음과 같이 구합니다.
시작 페이지 번호 + 페이지 총 사이즈 -1 과 총 페이지 수 중 더 작은 것!!
1 + 5 - 1 = 5 , 총 페이지 수 (9) 따라서 5
6 +5 -1 = 10 , 총 페이지 수 (9) 따라서 9
그러면 화면에 이렇게 보여줄수 있겠죠??
1,2,3,4,5
6,7,8,9
[pre와 next 구하기]
뭔가 허전하죠. pre와 next가 빠졌군요.. pre는 pre가 있을때 보여주거나 링크를 걸고 next 또한 마찬가지구요 어떤 조건을 붙일까요? pre는 페이지 스타트가 1이 아니면 되겠죠? next는 총 페이지 수보다 작으면 되겠군요.
그렇다면 페이지 표시는 다 나왔군요.
페이지를 눌렀을때 원하는 글의 범위를 셀렉트 하기 위해 글의 범위는 간단하죠. 현재 페이지 수 * 5 하면 마지막 글의 번호(이 번호는 범위 넘버 )가 나오겠죠?
1 * 5 = 5
6 * 5 = 35
여기서 다시 5를 빼면 시작 번호가 나오죠.
5 - 5 + 1 = 1;
35 - 5 +1 = 31;
현재 페이지수가 1일 경우는 1~5의 글을 보여주고 , 6일 경우 31~35의 글을 보여줍니다. 맞죠?
요것들만 아신다면 어떤 언어든 어떤 환경이든 페이징 처리에 어려움은 없을거라고 생각합니다.
페이징 처리 소스
지금까지 이야기한 걸 클래스로 구현해볼까요. 자바 언어이지만 이런 간단한건 어떤 언어로든 컨버전 가능하실거라 믿습니다.
public class Paging {
public int w_size = 5; // 글 개수
public int p_size = 5; // 페이지 개수
public int writing_Count = 0;
public int cur_Page = 0;
public Paging(int w_size, int p_size, int writing_Count, int cur_Page) {
super();
this.w_size = w_size;
this.p_size = p_size;
this.writing_Count = writing_Count;
this.cur_Page = cur_Page;
}
public int getPage_Count()
{
return ( (writing_Count - 1) / w_size) + 1;
}
public int getPage_Start()
{
return ( ( cur_Page - 1 ) / p_size ) * p_size + 1;
}
public int getPage_End()
{
return Math.min( getPage_Start() + p_size - 1 , getPage_Count() );
}
public boolean isPre()
{
return getPage_Start() != 1;
}
public boolean isNext()
{
return getPage_End() < getPage_Count();
}
public int getWriting_Start()
{
return getWriting_End() - w_size + 1;
}
public int getWriting_End()
{
return cur_Page * w_size;
}
public static void main(String[] args) {
// 여러가지 매개변수로 테스트 해보시기 바랍니다.
Paging pg = new Paging(5, 5, 26 , 6 );
// 총 글의 갯수는 select count(*) from board 하면 나오겠죠 ,
//현재 보고 있는 페이지 번호는 Default 1, 그리고 밑에 페이징에서 링크 걸린 i가 현재 페이지가 됩니다.
//Paging pg = new Paging(한 화면에 보여질 글 수 , 페이지 분할 수 , 총 글의 갯수 , 현재 보고 있는 페이지 번호 );
System.out.println("총 페이지 개수 : "+pg.getPage_Count());
System.out.println("페이지 시작 숫자 : "+pg.getPage_Start());
System.out.println("페이지 마지막 숫자 : "+pg.getPage_End());
System.out.println("Pre 표시 여부 : "+pg.isPre());
System.out.println("Next 표시 여부 : "+pg.isNext());
System.out.println("글 범위 시작 번호 : "+pg.getWriting_Start());
System.out.println("글 범위 끝 번호 : "+pg.getWriting_End());
System.out.println("select * from board where no between "+pg.getWriting_Start()+" and "+pg.getWriting_End());
// 이 셀렉트 결과를 화면에 뿌린 후에
// 밑에서 페이징을 하면 되겠죠? 이거에 링크를 걸고 i가 현재 페이지 번호로서 링크가 걸리게 되겠죠?
if(pg.isPre())
System.out.print(" Pre ");
for(int i = pg.getPage_Start(); i <= pg.getPage_End();i++)
{
System.out.print(" "+i+" ");
}
if(pg.isNext())
System.out.print(" Next ");
// 이런 페이징 클래스를 작성하여 사용하는 것이 여러모로 편리합니다. ~ ㅋㅋ
}
}