티스토리 뷰

공부 이야기

[JSP] 게시판 만들기3

판다(panda) 2011. 6. 20. 00:01
음.. 얼마 보는 사람이 없다고 생각했는데..
유입 키워드 순위에 올라가는것 보니까.. 꽤 많은 분들이 보시나봅니다..
물론 너무 허접한 게시판이라.. 슬쩍 보고 나갔을수도 있지만 말이죠;..

저번 게시판 만들기 2에서는 오라클DB 에 저장되어있는 것 까지 확인을 했었습니다..
오늘은 글 목록을 표시해봅시다..

글 목록을 DB에서 불러와야 하니까 오라클 연동 메소드를 적어놓구요..
글 목록 불러올 변수들도 설정해 봅시다..

'board_list.jsp'에 오라클 메소드를 추가합니다..
<%@ page contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR" %>
<%@ page language="java" import="java.util.*, java.sql.*, javax.servlet.http.*" %>

'board_wirte_insert.jsp'에 있는 오라클 메소드랑 동일합니다..
<%!
Connection DB_Connection() throws ClassNotFoundException, SQLException, Exception
{
String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
Class.forName( "oracle.jdbc.driver.OracleDriver" );
Connection conn = DriverManager.getConnection( url, "study", "study" );
return conn;
}

String TO_DB( String str ) throws Exception
{
if( str == null )
return null;
return new String( str.getBytes( "8859_1" ), "euc-kr" );
}
%>

<%
 Connection conn = DB_Connection();
 Statement stmt = null;
 ResultSet rs = null;

'board_wirte_insert.jsp'에서는 String 을 사용했는데요..
String은 배열 크기가 한정되어 있어서 런타임 크기 변경이 안됩니다.. 크기 증가는 가능하지만 말이죠..
메모리 허용 범위에서 런타임으로 크기 변경이 가능하게 Vector 를 사용할겁니다..

 Vector v_aid = new Vector();  
 Vector v_articleid = new Vector(); // article id 글 번호
 Vector v_name = new Vector();  // String 배열 크기 한정. 런타임 크기 변경 X, 크기 증가 가능
 Vector v_subject = new Vector(); // String 문자열 저장
 Vector v_date = new Vector();  // Vector 런타임 크기 변경 O, 메모리 허용 범위
 Vector v_hits = new Vector();  // Vector 객체 저장
 Vector v_memo = new Vector();
 Vector v_rid = new Vector();

시작 페이지 번호를 줘서.. 글이 많아지면 페이지를 넘길 수 있게 만들겁니다..
// 시작 페이지 번호 설정
 String str_c_page = request.getParameter( "str_c_page" );  
 if( str_c_page == null )
  str_c_page = "1";
 int c_page = Integer.parseInt( str_c_page );

그럼 페이지 관련 변수도 있어야 겠죠.. 총 페이지 수와, 시작페이지, 글이 몇개일때 페이지 넘어가는지 등을..
설정해줍니다..
 // 페이지 관련 변수 설정
 int total_cnt = 0;
 int list_num = 10;
 int start = 0;
 int t_page = 0;

이왕하는거 한번에 끝냅시다;..
원래 질질 끌면서.. 포스트 수 좀 늘리려고 했는데.. 귀찮아서 말이죠;..

게시판에 있는 기능이 뭐가 있겠습니까?.. 글쓰고, 글보고..
글이 300개인데.. 그 중에서 글 한개만 찾으려고 한다면 300개 다 넘겨서 봐야할까요?..
네.. 그래서 검색 기능을 넣을겁니다..

검색하기 참 쉽습니다.. 별거 아니에요.. 쿼리에 조건만 넣어주면 됩니다..
 String dbsearch = request.getParameter( "dbsearch" );
 if( dbsearch == null || dbsearch.trim( ).length( ) == 0 )
  dbsearch = "%";    // %로 검색 되면 전체적인 리스트 불러오기

이제 슬슬 쿼리 작성에 들어갑니다.. 

 try
{

 글이 몇개인지 카운트 해주구요.. 그 중에서 검색 조건을 만족하는 걸 찾으면 됩니다..
 조건 양옆에 % %을 넣어줘서 앞뒤로 검색을 하게됩니다..

 String sql_n = "select count(*) from board ";
  sql_n += "where dbsubject like '%" + dbsearch + "%'";// 검색 조건 설정

  stmt = conn.createStatement();
  rs = stmt.executeQuery( sql_n );

  if( rs.next() )
   total_cnt = rs.getInt(1);

  start = total_cnt - ( c_page - 1 ) * list_num;

  String sql_c = "";

여기도 쿼리.append()를 사용하거나, 아래처럼 쿼리를 작성하거나 편하신 방법으로 작성하면 되겠습니다..

  sql_c += "select aid, dbname, dbsubject, to_char( dbdate, 'yyyy/mm/dd hh:mi:ss' ), dbhits, dbmemo from ( ";
  sql_c += "select * from ( ";
  sql_c +=  "select * from ( ";
  sql_c +=   "select * from board order by rid asc ) ";
  sql_c +=  "where dbsubject like '%" + dbsearch + "%' ) ";
  sql_c += "where rownum <= " + start + " order by rid desc ) ";
  sql_c += "where rownum <= " + list_num;
  rs = stmt.executeQuery( sql_c );
  int title_len = 100;
  int aid = start;

쿼리가 실행되는 순서는 알고 계신가요?..

SELECT - (5)
FROM - (1)
WHERE - (2)
GROUP BY - (3)
HAVING - (4)
ORDER BY - (6)

이런 순으로 쿼리가 진행됩니다.. () 가 먼저 진행되는건 기본이구요..
((())) 가장 안에 있는 것 부터 천천히.. 위에있는 순서를 따라 진행하시면 어떻게 쿼리가 진행되는지 알수있을겁니다..

다음은 다음 글이 있을때 화면에 표시해주기 위해서 while로 내용이 있는지 돌려봅니다..

  while( rs.next() )
  {
   v_aid.addElement( Integer.toString( aid ) ); // v_aid.add(Integer.toString( aid )); 가능

addElement 는 벡터에만 있는 API 셋이고.. add는 JDK 1.2 에 추가된 Collection 인터페이스를 구현한것으로..
add 가 더 많이 쓰입니다.. 근데.. 저는 addElement 로 하는걸 먼저 봐서 말이죠;..
그래서 addElement 로 진행했습니다.. 

   v_articleid.addElement( Integer.toString( rs.getInt(1) ) );
   v_name.addElement( rs.getString(2) );
   v_subject.addElement( rs.getString(3) );
   v_date.addElement( rs.getString(4) );
   v_hits.addElement( Integer.toString( rs.getInt(5) ) );
   StringBuffer buf = new StringBuffer( rs.getString(6) );

   if( buf.length() > title_len )
   {
    buf.setLength( title_len );
    v_memo.addElement( buf + "..." );
   }
   else
    v_memo.addElement( buf );

   aid--;
  }
  stmt.close();
  rs.close();
 }
 catch( Exception e )
 {
  out.println( e.toString() );
 }
%>

이정도면 대충 된것 같네요.. 이제 테이블에 추가해서 눈으로 볼 수 있게 만들어 봅시다..

<html>
<head>
<title>게시판 목록</title>
</head>

총 게시물 수와.. 페이지 번호를 보여주겠다.. 고 전에 말했으니까.. 우선 위에 적어놓고
게시물이 몇개인지.. 현재 페이지는 어디인지를 알려주는 테이블을 하나 작성합니다..
<table cellspacing=1 width=700 border=0>
 <tr><td>총 게시물수: <%=total_cnt%></td><td><p align=right>페이지:<%= c_page %></td></tr>
</table>

<table cellspacing=1 width=700 border=1>
 <tr>
  <td width=50><p align=center>번호</p></td>
  <td width=100><p align=center>이름</p></td>
  <td width=320><p align=center>제목</p></td>
  <td width=100><p align=center>등록일</p></td>
  <td width=100><p align=center>조회수</p></td>
 </tr>
글 번호 만큼 반복해야하니.. for 문을 사용합니다..
<%
 for( int i=0; i<v_articleid.size(); i++ )
 {
%>
 <tr>
 <td width=50><p align=center><%=v_articleid.elementAt(i)%></p></td>
 <td width=100><p align=center><%=v_name.elementAt(i)%></p></td>
 <td width=320><p align=center><%=v_subject.elementAt(i)%></p></td>
 <td width=100><p align=center><%=v_date.elementAt(i)%></p></td>
 <td width=100><p align=center><%=v_hits.elementAt(i)%></p></td>
 </tr>
<%
 }
%>
페이지 번호도 만들어서 다음 페이지로 왔다갔다 해야하니까 페이지 번호도 만들어 놓구요..
<%
 if( ( total_cnt % list_num ) == 0 )
  t_page = total_cnt / list_num;
 else
  t_page = ( total_cnt / list_num ) + 1;

 int block_num = 5;
 int t_block = t_page / block_num;

 if( t_page % block_num != 0 )
  t_block++;
 
 int c_block = c_page / block_num;
 
 if( c_page % block_num != 0 )
  c_block++;
%>
</table>

<table width=700>
 <tr>
  <td><input type=button value="글쓰기" OnClick="window.location='board_write.jsp'"></td>
 </tr>
</table>

이제 테스트를 해봅시다.. 오라클 DB에 있는 데이터들은.. 싹 날렸습니다..
깨끗하게 확인하고 싶었거든요..

글 쓰기 내용을 이렇게 적고 저장!..



제대로 나오는군요..



"어랏.. 나는 글씨가 깨져나와.. 왜 이런거야?"..



글씨가 ?? 로 나온다는 것은.. 저장할때.. 한글을 제대로 저장 못했다는 것이죠..

'board_wirte_insert.jsp'에서 이게 제대로 동작을 못하는것인지..
아니면 변환이 필요없는건지 잘 모르겠지만.. 이게 문제인 것이죠..

 String TO_DB( String str ) throws Exception
 {
  if( str == null )
   return null;
  return new String( str.getBytes( "8859_1" ), "euc-kr" );
 }

'board_wirte_insert.jsp'에서 // dbname = TO_DB( dbname ); 주석 처리를 해서 테스트 해보세요..
?? 로 나오는 분들은 아마 제대로 될것입니다..

// dbname = TO_DB( dbname ); 만 써놨다고 이것만 하지 마시구요;..
TO_DB(); 쓰는 건 다 // 처리 해주세요..

물론 글은 다시 써야겠지요.. 기존에 저장된 글은 ?? 로 저장된 상태이기에..
// 해도 ?? 로 나옵니다..

아.. 만들고 보니.. 검색 기능도 빠졌고.. 글 내용을 어떻게 확인해야하는지.. 방법이 없네요..
이건 다음에 합시다.. 회의 들어가봐야해서요;..


오늘의 코드입니다..



저작권 표시 꼭!.. 상업적 이용 절대 불가!.. 컨텐츠 변경 안됨!..