지금까지 했던 파일들 최종본입니다. 제가 글 작성을 하면서 했던 파일입니다.



delete.jsp


delete_ok.jsp


list.jsp


modify.jsp


modify_ok.jsp


reply.jsp


reply_ok.jsp


view.jsp


write.jsp


write_ok.jsp






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

Posted by 세이나린
,

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

구글링을 해도 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 세이나린
,

이번에는 답글달기인 reply.jsp 와 reply_ok.jsp 를 만들겠습니다.


답글달기는 기존 글쓰기와는 다른점이 있습니다.

답글은 원게시물보다 아래에 출력이 되야하며 원게시물보다 들여쓰기가 되야합니다.

원게시물과 답글과의 출력순서를 위해 데이터베이스에 3가지의 필드를 추가시키겠습니다.


데이터베이스에 ref, indent, step 을 추가시킵니다. 형식은 int 즉 숫자 입니다.

ref는 부모의 글번호를 저장하는 필드이고

indent는 원글의 답글인지 답글의 답글인지를 구분하기위한 들여쓰기 입니다.

그리고 step은 같은 답글끼리의 출력순서를 위한 필드입니다.


우선 데이터베이스에 필드를 추가시키겠습니다.


기본값은 0으로 해놨습니다.


새로운 필드가 생겼기 때문에 write.jsp와 list.jsp도 수정해야하지만 답글을 완성후에 수정하도록 하겠습니다.


그리고 답글쓰기인 reply.jsp의 특징은 원글의 제목을 불러와서 입력이 되있어야 합니다.


본격적으로 reply.jsp파일과 relpy_ok.jsp을 생성후에 reply.jsp를 열어서 코드를 추가시킵니다.

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
 <title>게시판</title>
 </head>
 <body>
<table>
  <tr>
   <td>
    <table width="100%" cellpadding="0" cellspacing="0" border="0">
     <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>답글</td>
      <td width="5"><img src="img/table_right.gif" width="5" height="30" /></td>
     </tr>
    </table>
   <table>
     <tr>
      <td>&nbsp;</td>
      <td align="center">제목</td>
      <td><input name="subject" size="50" maxlength="100"></td>
      <td>&nbsp;</td>
     </tr>
     <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr>
    <tr>
      <td>&nbsp;</td>
      <td align="center">이름</td>
      <td><input name="name" size="50" maxlength="50"></td>
      <td>&nbsp;</td>
     </tr>
      <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr>
    <tr>
      <td>&nbsp;</td>
      <td align="center">비밀번호</td>
      <td><input name="name" size="50" maxlength="50"></td>
      <td>&nbsp;</td>
     </tr>
     <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr>
     <tr>
      <td>&nbsp;</td>
      <td align="center">내용</td>
      <td><textarea name="contents" cols="50" rows="13"></textarea></td>
      <td>&nbsp;</td>
     </tr>
     <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr>
     <tr height="1" bgcolor="#82B5DF"><td colspan="4"></td></tr>
     <tr align="center">
      <td>&nbsp;</td>
      <td colspan="2"><input type=button value="등록">
       <input type=button value="취소">
      <td>&nbsp;</td>
     </tr>
    </table>
   </td>
  </tr>
 </table>
</body

</html>


코드를 입력하시고 실행시키면


아직 제목에는 아무것도 없습니다. 연동을 안시켰기때문에..


이제 코드를 추가시키겠습니다.



<%@ page import="java.sql.*"%> 

SQL문을 이용하기 위한 import


<script language = "javascript"> // 자바 스크립트 시작

function replyCheck()
  {
   var form = document.replyform;
   
   if( !form.name.value )   // form 에 있는 name 값이 없을 때
   {
    alert( "이름을 적어주세요" ); // 경고창 띄움
    form.name.focus();   // form 에 있는 name 위치로 이동
    return;
   }
   
   if( !form.password.value )
   {
    alert( "비밀번호를 적어주세요" );
    form.password.focus();
    return;
   }
   
  if( !form.title.value )
   {
    alert( "제목을 적어주세요" );
    form.title.focus();
    return;
   }
 
  if( !form.memo.value )
   {
    alert( "내용을 적어주세요" );
    form.memo.focus();
    return;
   }
 
  form.submit();
  } 

</script>

자바스크립트 내용


<%
 	int idx = Integer.parseInt(request.getParameter("idx"));
 	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
	String url = "jdbc:odbc:board2";
	String id = "";
	String pass = "";
	String title = "";
	
	try {
		
		
		Connection conn = DriverManager.getConnection(url,id,pass);
		Statement stmt = conn.createStatement();

		
		String sql = "SELECT TITLE FROM board WHERE NUM=" + idx;
		ResultSet rs = stmt.executeQuery(sql);

 		if(rs.next()){
			title = rs.getString(1);
 		}
			
	rs.close();
	stmt.close();
	conn.close();
 	
} catch(SQLException e) {

} 

%>


view.jsp 에서 보낸 idx을 받아오고 SQL문을 이용해 idx값에 있는 title을 받아옵니다.


<form name=replyform method=post action="reply_ok.jsp?idx=<%=idx%>">

replys_ok.jsp 에 Get방식으로 idx를 추가해서 전송합니다.


<tr>
      <td>&nbsp;</td>
      <td align="center">제목</td>
      <td><input name="title" size="50" maxlength="100" value = "<%=title%>"></td>
      <td>&nbsp;</td

</tr>

제목에는 받아온 title을 입력해놓습니다.


<input type=button value="등록"  OnClick="javascript:replyCheck();"

<input type=button value="취소" OnClick="javascript:history.back(-1)">

버튼에 링크를 겁니다.


이제 list.jsp를 실행시켜서 확인을 해보겠습니다.

아 그러기전에 view.jsp 에 링크를 안시켰군요

<input type=button value="답글" OnClick="window.location='reply.jsp?idx=<%=idx%>'">



제목이 잘 입력이 되있네요.


reply.jsp의 최종 코드

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%> <%@ page import="java.sql.*"%> <script language = "javascript"> // 자바 스크립트 시작 function replyCheck() { var form = document.replyform; if( !form.name.value ) // form 에 있는 name 값이 없을 때 { alert( "이름을 적어주세요" ); // 경고창 띄움 form.name.focus(); // form 에 있는 name 위치로 이동 return; } if( !form.password.value ) { alert( "비밀번호를 적어주세요" ); form.password.focus(); return; } if( !form.title.value ) { alert( "제목을 적어주세요" ); form.title.focus(); return; } if( !form.memo.value ) { alert( "내용을 적어주세요" ); form.memo.focus(); return; } form.submit(); } </script> <% int idx = Integer.parseInt(request.getParameter("idx")); Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url = "jdbc:odbc:board2"; String id = ""; String pass = ""; String title = ""; try { Connection conn = DriverManager.getConnection(url,id,pass); Statement stmt = conn.createStatement(); String sql = "SELECT TITLE FROM board WHERE NUM=" + idx; ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ title = rs.getString(1); } rs.close(); stmt.close(); conn.close(); } catch(SQLException e) { } %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>게시판</title> </head> <body> <table> <form name=replyform method=post action="reply_ok.jsp?idx=<%=idx%>"> <tr> <td> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <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>답글</td> <td width="5"><img src="img/table_right.gif" width="5" height="30" /></td> </tr> </table> <table> <tr> <td>&nbsp;</td> <td align="center">제목</td> <td><input name="title" size="50" maxlength="100" value = "<%=title%>"></td> <td>&nbsp;</td> </tr> <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr> <tr> <td>&nbsp;</td> <td align="center">이름</td> <td><input name="name" size="50" maxlength="50"></td> <td>&nbsp;</td> </tr> <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr> <tr> <td>&nbsp;</td> <td align="center">비밀번호</td> <td><input name="password" size="50" maxlength="50"></td> <td>&nbsp;</td> </tr> <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr> <tr> <td>&nbsp;</td> <td align="center">내용</td> <td><textarea name="memo" cols="50" rows="13"></textarea></td> <td>&nbsp;</td> </tr> <tr height="1" bgcolor="#dddddd"><td colspan="4"></td></tr> <tr height="1" bgcolor="#82B5DF"><td colspan="4"></td></tr> <tr align="center"> <td>&nbsp;</td> <td colspan="2"><input type=button value="등록" OnClick="javascript:replyCheck();"> <input type=button value="취소" OnClick="javascript:history.back(-1)"> <td>&nbsp;</td> </tr> </table> </td> </tr> </table> </body

</html>



이제 reply_ok.jsp를 열어서 코드를 삽입합니다.


<%@ page import="java.sql.*"%>

SQL문을 이용하기 위한 import


<% request.setCharacterEncoding("euc-kr"); Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url = "jdbc:odbc:board2"; String id = ""; String pass = ""; String name = request.getParameter("name"); String password = request.getParameter("password"); String title = request.getParameter("title"); String memo = request.getParameter("memo"); int idx = Integer.parseInt(request.getParameter("idx")); try { int ref = 0; int indent = 0; int step = 0; Connection conn = DriverManager.getConnection(url,id,pass); Statement stmt = conn.createStatement(); String sql = "SELECT REF, INDENT, STEP FROM board WHERE NUM=" + idx; ResultSet rs = stmt.executeQuery(sql); if(rs.next()) { ref = rs.getInt(1); indent = rs.getInt(2); step = rs.getInt(3); } 


select문을 이용해서 idx 즉 원글의 ref, indent, step값을 가져옵니다.


sql = "UPDATE board SET STEP=STEP+1 where REF="+ref+" and STEP>" +step; 

stmt.executeUpdate(sql);

Update문을 이용해서 ref값이 불러온 ref와 같고 step이 불러온 step값보다 큰 자료들의 step을 +1 시키게 됩니다.


sql = "INSERT INTO board(USERNAME, PASSWORD, TITLE, MEMO, REF, INDENT, STEP) "+ "values(?,?,?,?,?,?,?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); pstmt.setString(2, password); pstmt.setString(3, title); pstmt.setString(4, memo); pstmt.setInt(5, ref); pstmt.setInt(6, indent+1); pstmt.setInt(7, step+1); pstmt.execute(); rs.close(); stmt.close(); pstmt.close(); conn.close(); }catch(Exception e) { } 

%>

insert문을 이용해서 데이터베이스에 자료를 입력합니다. reply.jsp에서 가져온 값들과 select문을 이용한 값들을 넣어 주되 ref는 같은 값을 넣고 indent와 step은 원글의 값보다 +1 시켜서 넣게 됩니다.


<script language=javascript> self.window.alert("입력한 글을 저장하였습니다."); location.href="list.jsp";  </script>

입력이 완료되면 목록으로 가게 됩니다.


reply_ok.jsp 최종코드


<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*"%>
<%
	request.setCharacterEncoding("euc-kr");

	Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

	String url = "jdbc:odbc:board2";
	String id = "";
	String pass = "";
	String name = request.getParameter("name");
	String password = request.getParameter("password");
	String title = request.getParameter("title");
	String memo = request.getParameter("memo");
	int idx = Integer.parseInt(request.getParameter("idx"));
	
	try {
		int ref = 0;
		int indent = 0;
		int step = 0;

		Connection conn = DriverManager.getConnection(url,id,pass);
		Statement stmt = conn.createStatement();
		
		String sql = "SELECT REF, INDENT, STEP FROM board1 WHERE NUM=" + idx;
		ResultSet rs = stmt.executeQuery(sql);
		
		if(rs.next()) {
			ref = rs.getInt(1);
			indent = rs.getInt(2);
			step = rs.getInt(3);
		}
		
		sql = "UPDATE board1 SET STEP=STEP+1 where REF="+ref+" and STEP>" +step;
		stmt.executeUpdate(sql);
		
		sql = "INSERT INTO board1(USERNAME, PASSWORD, TITLE, MEMO, REF, INDENT, STEP) "+
				"values(?,?,?,?,?,?,?)";
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, name);
		pstmt.setString(2, password);
		pstmt.setString(3, title);
		pstmt.setString(4, memo);
		pstmt.setInt(5, ref);
		pstmt.setInt(6, indent+1);
		pstmt.setInt(7, step+1);
		
		pstmt.execute(); 
		rs.close();
		stmt.close();
		pstmt.close();
		conn.close();
		
	}catch(Exception e) {
		
	}
%>
  <script language=javascript>
   self.window.alert("입력한 글을 저장하였습니다.");
   location.href="list.jsp";
  </script>


모든 코드를 입력하고 list.jsp를 실행시켜서 답글을 달아보도록 하겠습니다.


테스트1번 글에 답글누르고 글을 작성했습니다.


현재는 글번호로 내림차순 정렬이 되어있기 때문에 원글보다 위로 가있는걸 확인할 수 있습니다.

그래도 확인겸 데이터베이스를 보겠습니다.



보시면 indent와 step이 원글보다 +1 된걸 확인하실수 있지만

ref는 그대로 0인걸 보실수 있습니다. 이유는 원글의 ref가 0이기 때문입니다.

우선 수작업으로 원글과 답글의 값을 1로 저장하겠습니다.

왜냐하면 아직 글쓰기 파일인 write.jsp파일을 수정을 안했기 때문에 ref는 0으로 들어가기때문입니다.

부모글을 1로 바꿨기 때문에 답글의 답글을 한번 달아보겠습니다.



5번 게시물은 1번의 답글의 답글을 단 게시물입니다. ref는 원글의 값을 가져갔고 indent와 step은 2가 된걸 확인할 수 있습니다.


이제 write_ok.jsp로 가서 ref값을 추가시키겠습니다.


int max = 0; try { Connection conn = DriverManager.getConnection(url,id,pass); Statement stmt = conn.createStatement(); String sql = "SELECT MAX(NUM) FROM board"; ResultSet rs = stmt.executeQuery(sql); if(rs.next()){ max=rs.getInt(1); } sql = "INSERT INTO board(USERNAME,PASSWORD,TITLE,MEMO,REF) VALUES(?,?,?,?,?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, name); pstmt.setString(2, password); pstmt.setString(3, title); pstmt.setString(4, memo); pstmt.setInt(5, max+1); pstmt.execute(); pstmt.close(); stmt.close(); conn.close(); } catch(SQLException e) { out.println( e.toString() ); }

write_ok.jsp의 중간에 추가시킨 내용들입니다.

int max라는 변수를 선언했고

select문으로 Num의 max값을 받아왔습니다. 왜냐하면 글번호는 현재의 제일 높은 번호보다 +1이 되어 만들어지기 때문에 자신의 글번호를 ref넣기 위한 방법입니다.

그리고 insert문에 ref값을 추가시키고 값은 max+1을 해서 삽입합니다.


이제 출력순서를 바꿔주기 위해 list.jsp를 손보도록 하겠습니다.


String sqlList = "SELECT NUM, USERNAME, TITLE, TIME, HIT, INDENT from board order by REF DESC, STEP ASC";

list.jsp의 select문에 indent를 추가검색 합니다. 또한 기존에는 Num즉 글번호를 이용한 정렬이였지만 답글이 있기 때문에 글번호정렬이 아닌 REF와 STEP을 이용한 정렬을 하겠습니다.

Ref즉 원글의 글번호를 기준으로 내림차순, Step을 기준으로 오름차순을 합니다.


그리고 답글인지를 표시하기 위해 이미지를 한개 더 추가시키고 들여쓰기를 하도록 코드를 추가시킵니다.


<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%>"><%=title %></td>

중간에 보시면 title을 출력하는곳에 이렇게 코드를 추가시킵니다. 그리고 이미지를 img폴더에 추가시킵니다.



반복문을 이용해서 들여쓰기를 넣었고, 답글일경우 이미지를 표시하도록 조건문을 걸었습니다.


이제 list.jsp를 실행하도록 하겠습니다.



답글이 순서대로 잘 달리고 있는걸 확인했습니다.


이제 남은건 페이징처리가 남아있네요



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

Posted by 세이나린
,