[개발] 게시판 페이징 처리의 원리와 소스

in #kr-dev7 years ago

과거 제가 개발 기초를 배울 때 나름 정리를 해두었던건데 이곳에 다시 제대로 정리를 해봅니다.

처음 실무를 접하며 가장 기본 중 하나가 페이징 처리라고 생각합니다. (아... 아닌가? ㅋㅋ) 원리를 이야기해서 어떤 언어든, 환경이든 익혀서 사용했으면 합니다. 아시는분도 다 까먹으셨을테니 오랜만에 다시 보시면 리마인드 되실겁니다. ㅋㅋㅋ

'그까이꺼 대충 페이징 유틸, 라이브러리 갖다 쓰면 돼'라고 생각할수도 있겠지만 환경이 항상 가져다 쓸수 있는건 아니니까요.


페이징 처리의 원리

먼저 두가지만 정리하고 가면 됩니다.

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 ");
  
  // 이런 페이징 클래스를 작성하여 사용하는 것이 여러모로 편리합니다. ~ ㅋㅋ
  
 }
 
}

Sort:  

개발 내용은 잘 모르겠지만... 스팀잇도 내 블로그만이라도 페이징 처리 좀 해주면 좋겠네요. 가끔 전에 쓴 글 좀 살펴보려면 스크롤을 한세월 해야 해서 너무 불편해요.ㅠㅠ

그렇네요 아이디어를 좀 올려봐도 좋을것 같네요 지금 방식 너뭉불편함 .. ㅜㅜ 글 보다가 다시 볼라치면 회귀되어있고. 어디까지 봤는지도 헷갈리구요...

스팀미는 여러분의 친구입니드...아

애용하고 있습니다. ㅋㅋㅋ

눈팅만 합니다. ㅎㅎ

ㅎㅎㅎ 네 오로지 개발자용입니당 ㅎㅎ 것두 외부...ㅎㅎ

우오아아아 멋있습니다 ㅎㅎ

학생때 개인프로젝트 같은걸로 배우지 않는다면... 신입으로 들어가서 얼마지나지 않아 익히게 되는데... 음... 요즘은 그냥 라이브러리나 유틸을 가져다 쓰는 분위기가 강한 것 같습니다. 그런건 좀 아쉬워요...

만들어보면서 배우는게 재미있습니다 ㅎㅎ자바는 한번도 안해봤는데, 물론 다른 언어도 해봤다고 하긴 그런 수준이지만...되게 소스 코드가 눈에 보기 좋게 되어있는거 같습니다 ㅎㅎ

ㅋㅋㅋ 맞아요 만들어보면서 배우는게 젤 좋죠. 소스는 정말 ㅡ.ㅡ... 저 공부할때 만들었을걸요? ㅋㅋㅋ

이거슨 아주 아주 오래전에 asp로 만들어본 게시판 사이트의 그것이군요..... 그때의 추억이 막 생각나네요 ㅋㅋ 그때 페이징도 완전 쌩으로 다 개발 했었는데.... 요즘엔 진짜 편한거같아요 ㅎㅎ

저한테도 그정도니 베어님껜 완전 응답하라 1988 같을 것 같습니다. ㅋㅋㅋ 저도 이걸 다시 정리하면서 추억에 잠겼었다는~ ㅎㅎㅎ

담아갑니다! 감사합니다! 나중에 시간 여유 생기면 또 몰아서 이것저것 해봐야겠네요 ㅎㅎ

저도 이런 도전적인 이웃님들 땜에 더 열심히 하게됩니다 ㅋㅋ

아...역시 제겐 너무 어려운 이야깁니다.
제가 아는 거라곤 밥 아저씨 분입니다. ㅎㅎㅎ

밥 아찌로서 강제 공감대형성 성공 ㅋㅋㅋ

밥 아저씨 오랜만에 뵙네요. ㅋㅋ 참 쉽죠?

저,, 위의 [페이지번호 구하기] 파트에서 오류가 있군뇨. 7이 나와야...

음... 댓글 감사합니다. 첫시작페이지 번호이기에 6이 맞는것 같습니다. ^^ 현재 페이지를 구하는게 아니에요

Coin Marketplace

STEEM 0.27
TRX 0.26
JST 0.039
BTC 94318.75
ETH 3339.82
USDT 1.00
SBD 3.45