페이징 처리를 할때 고민을 가장 많이 했던것 같습니다.

구글링을 해도 ms access가 아닌 my sql이나 다른 데이터베이스에서 한 자료들이 많았고

그 중 페이징에 쓰여진 코드는 저에게 맞지 않았습니다. 

페이징의 원리는 해당 페이지마다 정해놓은 개수만큼만 출력되게 하는것인데 SQL문을 많이 안써본 저로써는 좀 엉망인 코드를 만든것 같지만 만족스러운 결과를 보였습니다.

실제로 이런 코드는 효율이 비효율적인것 같아서 다음에 model1 을 이용한 게시판 만들기에서는 이 엉망인 정렬법을 제외시킬 예정입니다.


일단 페이징 테스트를 위해 데이터베이스에 자료들을 추가시켰습니다. list.jsp에서 글쓰기로 다 작성했어요~ㅋㅋㅋ




26개의 자료가 있네요. 게시판이라고 하기에는 26개도 많은건 아니지만 테스트용으론 충분한 양입니다.

페이징을 하기전에 날짜를 비교해서 오늘 쓴 글이면 게시물 제목 끝에 new표시를 하게 하겠습니다.

그리고 작성일도 너무 길기 때문에 줄여서 출력시키도록 하겠습니다.


<%@ page import="java.sql.*,java.text.SimpleDateFormat,java.util.Date"%>

기존에 sql.*만 import 시켰지만 추가적으로 SimpleDateFormat 과 Date를 추가 import 시킵니다.


while(rs.next()) { int idx = rs.getInt(1); String name = rs.getString(2); String title = rs.getString(3); String time = rs.getString(4); int hit = rs.getInt(5); int indent = rs.getInt(6); Date date = new Date(); SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd"); String year = (String)simpleDate.format(date); String yea = time.substring(0,10); %>

그리고 이곳에 Date 부터 4줄을 더 추가시킵니다.

년/월/일으로 날짜를 표시하고, 데이터베이스에 있는 날짜와 비교하기 위해 포멧을 같게 바꾸는 작업입니다.


%>
	<a href="view.jsp?idx=<%=idx%>"><%=title %></a>
<%
	if(year.equals(yea)){
%>
			<img src='img/new.jpg' />
<%
		}  
%>

제목이 있는 곳에 제목 뒷 부분에

조건문을 달아서 이미지를 추가시킵니다.

이미지는

이것을 사용했습니다.

...게시물을 오늘 99% 올렸더니 다 붙어있네요...머 중요한것은 아니고.. 작성일도 좀더 심플하게 바뀌었습니다.


본격적으로 페이징을 위하여 변수를 살펴보겠습니다.


<% final int ROWSIZE = 4; // 한페이지에 보일 게시물 수 final int BLOCK = 5; // 아래에 보일 페이지 최대개수 1~5 / 6~10 / 11~15 식으로 5개로 고정 int pg = 1; //기본 페이지값 if(request.getParameter("pg")!=null) { //받아온 pg값이 있을때, 다른페이지일때 pg = Integer.parseInt(request.getParameter("pg")); // pg값을 저장 } int start = (pg*ROWSIZE) - (ROWSIZE-1); // 해당페이지에서 시작번호(step2) int end = (pg*ROWSIZE); // 해당페이지에서 끝번호(step2) int allPage = 0; // 전체 페이지수 int startPage = ((pg-1)/BLOCK*BLOCK)+1; // 시작블럭숫자 (1~5페이지일경우 1, 6~10일경우 6) int endPage = ((pg-1)/BLOCK*BLOCK)+BLOCK; // 끝 블럭 숫자 (1~5일 경우 5, 6~10일경우 10) %>


                String sqlCount = "SELECT COUNT(*) FROM board1";
		ResultSet rs = stmt.executeQuery(sqlCount);
		
		if(rs.next()){
			total = rs.getInt(1);
		}

		int sort=1;
		String sqlSort = "SELECT NUM from board1 order by ref desc, step asc";
		rs = stmt.executeQuery(sqlSort);
	
		
		while(rs.next()){
			int stepNum = rs.getInt(1);
			sql = "UPDATE board1 SET STEP2=" + sort + " where NUM=" +stepNum;
		 	stmt1.executeUpdate(sql);
		 	sort++;
		} 


기존의 코드에 추가시킵니다.

sort라는 변수를 1로 초기화 시킵니다.

그리고 미리 데이터베이스의 값을 정렬합니다.

후에 값을 찾으면서 Update를 합니다. step2에 1부터 끝까지 수정을 합니다.


이런식으로 step2에 1부터 끝까지 숫자가 생깁니다. 

list.jsp에 올때마다 Update가 발생하기 때문에 효율은 좋지 않다고 생각됩니다. 다음 게시판에는 쓰지 않을 내용입니다.


allPage = (int)Math.ceil(total/(double)ROWSIZE);
		
		if(endPage > allPage) {
			endPage = allPage;
		}
		
		out.print("총 게시물 : " + total + "");
		
		String sqlList = "SELECT NUM, USERNAME, TITLE, TIME, HIT, INDENT from board1 where STEP2 >="+start + " and STEP2 <= "+ end +" order by step2 asc";
		rs = stmt.executeQuery(sqlList);
		 

%>


allPage를 설정합니다. 총 게시물의 수에 맞게 총페이지를 정합니다. 저는 26개의 게시물이 있고 4개씩 보기때문에 총 7페이지가 필요합니다. 계산식을 보시면 ceil이라는 함수는 올림함수입니다. 20개의 게시물이라면 5페이지 21개라면 6페이지가 필요합니다. 이것을 올림함수로 계산한 내용입니다.


그리고 endPage가 allPage 보다 크게 될시 endPage를 allPage의 값으로 바꿉니다.

그리고 정렬을 하되 start부터 end까지 step2를 오름차순기준으로 출력을 합니다. 


그리고 맨아래쪽 글쓰기 버튼 바로 위에 코드를 추가시킵니다.


<table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr><td colspan="4" height="5"></td></tr>
  <tr>
	<td align="center">
		<%
			if(pg>BLOCK) {
		%>
			[<a href="list.jsp?pg=1">◀◀</a>]
			[<a href="list.jsp?pg=<%=startPage-1%>"></a>]
		<%
			}
		%>
		
		<%
			for(int i=startPage; i<= endPage; i++){
				if(i==pg){
		%>
					<u><b>[<%=i %>]</b></u>
		<%
				}else{
		%>
					[<a href="list.jsp?pg=<%=i %>"><%=i %></a>]
		<%
				}
			}
		%>
		
		<%
			if(endPage<allPage){
		%>
			[<a href="list.jsp?pg=<%=endPage+1%>"></a>]
			[<a href="list.jsp?pg=<%=allPage%>">▶▶</a>]
		<%
			}
		%>
		</td>
		</tr>
		  <tr align="center">
   <td><input type=button value="글쓰기" OnClick="window.location='write.jsp'"></td>
  </tr

</table>

첫번쨰if문을 보면 BLOCK값은 5이고 이 값보다 pg값이 크게되면 화살표를 생성하는 내용입니다.

예를들어 6페이지일경우 나오게되겠죠

그 아래는 차례대로 페이지를 표시하는 내용입니다.


저장을 하고 실행을 하면



페이지가 생겼네요!


아? 그러고보니 수정할 내용이 더 생겼습니다.

기존에는 idx값들만 전달했지만 이제는 pg값도 함께 보내줘야 하기때문에

list ->view 에 pg값을 전달

view ->list 에 pg값을 전달

view ->modify ->modify_ok에 pg값을 전달

view ->delete -> delete_ok 에 pg값을 전달

view ->reply -> reply_ok 에 pg값을 전달


각 페이지에

int pg = Integer.parseInt(request.getParameter("pg"));

값을 추가시키고 전달 하는 곳에

<a href="view.jsp?idx=<%=idx%>&pg=<%=pg%>"><%=title %></a>


<input type=button value="답글" OnClick="window.location='reply.jsp?idx=<%=idx%>&pg=<%=pg%>'"> <input type=button value="목록" OnClick="window.location='list.jsp?pg=<%=pg%>'"> <input type=button value="수정" OnClick="window.location='modify.jsp?idx=<%=idx%>&pg=<%=pg%>'"> <input type=button value="삭제" OnClick="window.location='delete.jsp?idx=<%=idx%>&pg=<%=pg%>'">

이런식으로 pg값도 전달합니다.


list.jsp 최종코드

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*,java.text.SimpleDateFormat,java.util.Date"%>

<%
	final int ROWSIZE = 4;
	final int BLOCK = 5;

	int pg = 1;
	
	if(request.getParameter("pg")!=null) {
		pg = Integer.parseInt(request.getParameter("pg"));
	}
	
	int start = (pg*ROWSIZE) - (ROWSIZE-1);
	int end = (pg*ROWSIZE);
	
	int allPage = 0;
	
	int startPage = ((pg-1)/BLOCK*BLOCK)+1;
	int endPage = ((pg-1)/BLOCK*BLOCK)+BLOCK;

%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
 <title>게시판</title>
 </head>
 <body>
 <%
	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
	String url = "jdbc:odbc:board2";
	String id = "";
	String pass = "";
	int total = 0;
	
	try {
		Connection conn = DriverManager.getConnection(url,id,pass);
		Statement stmt = conn.createStatement();
		Statement stmt1 = conn.createStatement();
		String sql = "";

		String sqlCount = "SELECT COUNT(*) FROM board1";
		ResultSet rs = stmt.executeQuery(sqlCount);
		
		if(rs.next()){
			total = rs.getInt(1);
		}

		int sort=1;
		String sqlSort = "SELECT NUM from board1 order by ref desc, step asc";
		rs = stmt.executeQuery(sqlSort);
	
		
		while(rs.next()){
			int stepNum = rs.getInt(1);
			sql = "UPDATE board1 SET STEP2=" + sort + " where NUM=" +stepNum;
		 	stmt1.executeUpdate(sql);
		 	sort++;
		}
		
		allPage = (int)Math.ceil(total/(double)ROWSIZE);
		
		if(endPage > allPage) {
			endPage = allPage;
		}
		
		out.print("총 게시물 : " + total + "");
		
		String sqlList = "SELECT NUM, USERNAME, TITLE, TIME, HIT, INDENT from board1 where
 STEP2 >="+start + " and STEP2 <= "+ end +" order by step2 asc";
		rs = stmt.executeQuery(sqlList);
		
%>
<table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr height="5"><td width="5"></td></tr>
 <tr style="background:url('img/table_mid.gif') repeat-x; text-align:center;">
   <td width="5"><img src="img/table_left.gif" width="5" height="30" /></td>
   <td width="73">번호</td>
   <td width="379">제목</td>
   <td width="73">작성자</td>
   <td width="164">작성일</td>
   <td width="58">조회수</td>
   <td width="7"><img src="img/table_right.gif" width="5" height="30" /></td>
  </tr>
<%
	if(total==0) {
%>
	 		<tr align="center" bgcolor="#FFFFFF" height="30">
	 	   <td colspan="6">등록된 글이 없습니다.</td>
	 	  </tr>
<%
	 	} else {
	 		
		while(rs.next()) {
			int idx = rs.getInt(1);
			String name = rs.getString(2);
			String title = rs.getString(3);
			String time = rs.getString(4);
			int hit = rs.getInt(5);
			int indent = rs.getInt(6);
			
			Date date = new Date();
			SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd"); 
			String year = (String)simpleDate.format(date);
			String yea = time.substring(0,10);
		
%>
<tr height="25" align="center">
	<td>&nbsp;</td>
	<td><%=idx %></td>
	<td align="left">
	<% 
		
	for(int j=0;j<indent;j++){
%>		&nbsp;&nbsp;&nbsp;<%
	}
	if(indent!=0){
%>		<img src='img/reply_icon.gif' />
<%
	}
%>
	<a href="view.jsp?idx=<%=idx%>&pg=<%=pg%>"><%=title %></a>
<%
	if(year.equals(yea)){
%>
			<img src='img/new.jpg' />
<%
		} 
%>
	</td>
	<td align="center"><%=name %></td>
	<td align="center"><%=yea %></td>
	<td align="center"><%=hit %></td>
	<td>&nbsp;</td>
</tr>
  <tr height="1" bgcolor="#D2D2D2"><td colspan="6"></td></tr>
<% 
		}
	} 
	rs.close();
	stmt.close();
	conn.close();
} catch(SQLException e) {
//	out.println( e.toString() );
}
%>
 <tr height="1" bgcolor="#82B5DF"><td colspan="6" width="752"></td></tr>
 </table>
 
<table width="100%" cellpadding="0" cellspacing="0" border="0">
  <tr><td colspan="4" height="5"></td></tr>
  <tr>
	<td align="center">
		<%
			if(pg>BLOCK) {
		%>
			[<a href="list.jsp?pg=1">◀◀</a>]
			[<a href="list.jsp?pg=<%=startPage-1%>"></a>]
		<%
			}
		%>
		
		<%
			for(int i=startPage; i<= endPage; i++){
				if(i==pg){
		%>
					<u><b>[<%=i %>]</b></u>
		<%
				}else{
		%>
					[<a href="list.jsp?pg=<%=i %>"><%=i %></a>]
		<%
				}
			}
		%>
		
		<%
			if(endPage<allPage){
		%>
			[<a href="list.jsp?pg=<%=endPage+1%>"></a>]
			[<a href="list.jsp?pg=<%=allPage%>">▶▶</a>]
		<%
			}
		%>
		</td>
		</tr>
		  <tr align="center">
   <td><input type=button value="글쓰기" OnClick="window.location='write.jsp'"></td>
  </tr>
 </table>
 </body

</html>


이제 실행해봅니다.


여기서 한가지 안건든정보가 있긴합니다.

답글이 달렸을때 글이 삭제되면 변화를 주는부분도 생각을 해봤는데 

게시판의 큰 틀을 해보는걸로 만족하고 여기서 끝냈습니다.


더 해보실 분은 데이터베이스에 필드를 하나 더 추가시킨뒤에 원글이 삭제되었을시 답글에 특정 값을 Update시켜서 원글이 삭제된 답글이라고 표시하는 방법도 있으니 해보시길 바랍니다.


시간이 되는데로 MODEL 1 방식의 게시판을 게시하도록 하겠습니다.




이미지출처 : 판다의 이상한 블로그(http://ssppmm.tistory.com/)





Posted by 세이나린
,