티스토리 뷰

오늘 테이블 등록하기로 했는데요.. 그전에 잠깐 다른것부터 하고 진행하겠습니다..

기본적으로 Web Application 디렉토리는 이런 구조로 되어있습니다..



여기서 중점을 둬야할 부분은 WEB-INF 인데요..
이 폴더는 서버가 읽어오는 파일들을 넣어두는 곳입니다..

lib 폴더에는 .jar 파일을 넣고.. classes 폴더는 클래스/패키지 등의 파일을..
src 는 일반적인 소스코드 파일을 넣습니다..

이메일 보낼땐 lib 폴더에 메일보내기 관련 .jar 을 넣어둬야합니다..

인터넷에 DBConnection.java 라고 검색해보시면 여러개가 나오는데요..


그리고 이제 WEB-INF도 소개시켜줬겠다.. 슬슬 진행하면 될것 같군요..
이부분을 잘 모르겠다 하시는 분은 톰켓에서 Tomcat DBCP 설정부터 하고.. 기본 서적을 보시면 될것 같습니다..

요새는 이클립스 쓰고 하니까.. 아마 쉽게 할 수 있을꺼에요.. 저처럼 Editplus 로만 코딩하시는 분은 별로 없을것 같네요..

우선 전 테이블 같은 경우.. 쓸때없는것이 너무 많았습니다.. 그런거 다 잘라 버리고 진행할겁니다..
전에는 댓글 다는 기능도 없었는데.. 댓글 번호까지 삽입을 했었습니다.. 그래서 그런지.. 질문이 많이 들어오더라구요..
그래서 빼겠습니다.. 댓글 기능은 다른 곳 찾아보세요.. 이것도 책 같은거 보면 있을지도 한번 찾아보세요..

글번호, 제목, 이름, 등록일자 정도만 넣겠습니다..
이게 JSP 강좌이지 DB 강좌는 아니니까 말이죠..

CREATE TABLE NEWBOARD
(
  SEQ      NUMBER        PRIMARY KEY NOT NULL,
  NAME VARCHAR2(50 BYTE),
  SUBJECT  VARCHAR2(200 BYTE),
  CONTENT  CLOB,
  REGDATE  DATE
)

primary key 는 번호 하나만 잡았습니다.. 어짜피 번호는 겹치는게 없을테니말이죠..

나중에 칼럼이 10-20개 되고, 테이블이 10-20개 되었을때.. 키값 잘 잡으셔야합니다.. 잘 못 잡으면 인생이 고달퍼져요..

하고 보니.. 공지사항 만들기랑 똑같네요.. user_id 가 name 으로 바뀐것만 빼구요;..

시퀀스도 하나 만들어줍니다..

CREATE SEQUENCE NEWBOARD_SEQ
START WITH 0
MAXVALUE 999999999999999999999999999
MINVALUE 0
NOCYCLE
NOCACHE
NOORDER;

DB에서 만들건 다 만들었네요..

저는 몰래 회사 서버에 기생하고 있기 때문에.. 톰켓을 건드릴수없습니다;..
건드리면 톰켓 내렸다가 다시 올려야하는데.. 그럼 업무지장이 있거든요;..

저는 기존의 방식대로 하겠습니다..

<%@ page language="java" import="java.sql.*,java.util.*,java.io.*,util.*" contentType="text/html;charset=euc-kr" %>
<%@ page import = "oracle.sql.CLOB" %>
요 부분이 없다면 CLOB 할때 에러나옵니다..

<%!
 Connection DB_Connection() throws ClassNotFoundException, SQLException, Exception
 {
  String url = "jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:ORA2012";
  String username = "study";
  String userpass = "study";
  Class.forName( "oracle.jdbc.driver.OracleDriver" );
  Connection conn = DriverManager.getConnection( url, username, userpass );
  return conn;
 }
%>

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

 String name = request.getParameter("name");
 String subject = request.getParameter("subject");
 String contents = request.getParameter("contents");
 요 부분이 newboard_add 에서 넘어온 값들을 받는 부분입니다..

 try
 {
  stmt = conn.createStatement();
  query = new StringBuffer();

  String seq = "";

  query.setLength(0);
  query.append("SELECT NEWBOARD_SEQ.NEXTVAL AS SEQ FROM DUAL");
  rs = stmt.executeQuery(query.toString());
  if (rs.next()) {
   seq = rs.getString("SEQ");
  }
  rs.close();
 이 부분은 편하게 번호를 저장하기 위해서 시퀀스 번호를 불러오는 부분입니다..

  query.setLength(0);
  query.append("INSERT INTO NEWBOARD ( SEQ, NAME, SUBJECT, CONTENTS )")
    .append("VALUES ( '"+seq+"', '"+name+"', '"+subject+"', empty_clob() )");
  stmt.executeUpdate(query.toString());
  여기서 번호, 이름, 글 제목을 입력하고 글 내용 부분은 empty_clob()를 사용해서 그냥 넘어가줍니다..
  
  conn.setAutoCommit(false);
  이게 없다면 java.sql.SQLException: ORA-01002: 인출 시퀀스가 틀립니다. 라고 나올겁니다..
  자동 커밋을 못하게 막아놓습니다..

  query.setLength(0);
  query.append("SELECT CONTENTS FROM NEWBOARD WHERE SEQ= '"+seq+"' FOR UPDATE ");
  여기서 CLOB 에 내용을 채워넣습니다..
  요새는 이렇게 안하고 insert에 바로 clob 를 넣어도 된다고 하던데.. 뭐가 문제인지 잘 안되더라구요;..
  확실히 되는 방법을 기술하기 위해서.. 옛날 방식의 코딩 방법을 적어봤습니다..

  rs = stmt.executeQuery( query.toString() );
  if ( rs.next() )
  {
   CLOB clob = (CLOB)rs.getClob(1);
   Writer writer = clob.getCharacterOutputStream();
   Reader src = new CharArrayReader(contents.toCharArray());
   char[] buffer = new char[1024];
   int read = 0;
   while ( (read = src.read(buffer,0,1024)) != -1) {
    writer.write(buffer, 0, read);
   }
   src.close();
   writer.close();

   conn.commit();
   conn.setAutoCommit(true);
   커밋을 하고 자동 커밋으로 바꿔줍니다..

  }

 } catch( Exception e ) {
  out.println( e.toString() );
 }

out.println("<SCRIPT>parent.location.href='/newboard/newboard_list.jsp';</SCRIPT>");
완료 후 리스트 페이지로 넘어갑니다..
%>

테스트 한번 해봅시다..



등록을 누르면.. 리스트 페이지로 옮겨와지긴 하는데 아무것도 안나오죠..



당연한겁니다.. 리스트 페이지는 딱 저것만 나오게 만들었으니까 말이죠..

토드나 sqlplus 또는 각종 프로그램으로 저장된 데이터를 확인해줍니다..



글 번호 1, 이름 판다(panda), 제목 판다의 3번 게시판, 내용 판다의 3번째 게시판입니다. 가 모두 성공적으로 저장되었습니다..


DBConnection 이 제대로 작동한다면..
<%@ page language="java" import="java.sql.*,java.util.*,java.io.*,util.*" contentType="text/html;charset=euc-kr" %>
<%@ page import = "oracle.sql.CLOB" %>
<%!
Connection DB_Connection() throws ClassNotFoundException, SQLException, Exception
{
String url = "jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:ORA2012";
String username = "study";
String userpass = "study";
Class.forName( "oracle.jdbc.driver.OracleDriver" );
Connection conn = DriverManager.getConnection( url, username, userpass );
return conn;
}
%>

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

이 부분은 이렇게 줄어들게 됩니다..

<%@ page language="java" import="java.sql.*,java.util.*,java.io.*,util.*" contentType="text/html;charset=euc-kr" %>
<%@ page import = "oracle.sql.CLOB" %>
<%
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
StringBuffer query = null;

그런데 톰켓을 죽일수없으니;.. 어쩔수없네요.. DBConnection 했는데 안되신다구요?.. 그냥 저처럼 그렇게 하세요;..

우선 등록 확인은 된것 같으니 리스트 페이지에 출력을 해줘야겠죠..
newboard_list.jsp 를 열어서 소스를 추가해줍니다..
<%@ page language="java" import="java.sql.*,java.util.*,java.io.*,util.*" contentType="text/html;charset=euc-kr" %>

<%!
 Connection DB_Connection() throws ClassNotFoundException, SQLException, Exception
 {
  String url = "jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:ORA2012";
  String username = "study";
  String userpass = "study";
  Class.forName("oracle.jdbc.driver.OracleDriver");
  Connection conn = DriverManager.getConnection(url, username, userpass);
  return conn;
 }
%>
오라클 메소드를 추가해줍니다.. 위에서도 계속 썼지만.. DBConnection 되면 안써도 됩니다..

<html>
<head>
<title>3번 게시판</title>
</head>
<body>

<table width="100%" cellpadding="0" cellspacing="0" border="0">
 <tr height="5"><td></td></tr>
 <tr style="background:url('/newboard/img/table_mid.gif') repeat-x; text-align:center;">
  <td width="5"><img src="/newboard/img/table_left.gif" width="5" height="30" /></td>
  <td>번호</td>
  <td>제목</td>
  <td>이름</td>
  <td>등록일자</td>
  <td width="5"><img src="/newboard/img/table_right.gif" width="5" height="30" /></td>
 </tr>


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

 String totalCount = "";   글 총 개수 입니다..
 String link = "";           글 검색했을때 현재 페이지 기억하기 위해 미리 만들어뒀습니다..
 String page_num = request.getParameter("page_num"); 
 String pages = request.getParameter("pages");
       페이지 넘버와 페이지s도 다음 3번 글에서 확인하시구요;..
 String s_name = "";      그냥 name 하면 헷갈리니까 s_ 를 붙여서 search 앞글자 s를 붙였습니다..
 String s_subject = "";    위와 마찬가지죠..

 int page_no = 20;         페이지 넘어가기 위한 숫자인데.. 현재는 20입니다..
                                         기존의 소스가 페이지 넘김이 없어서 불편하다고 해서요..
                                         다음 게시판3 글 쓸때.. 값을 바꿀겁니다.. 이건 뭐 다음에 다시 설명하고 넘어가죠..

 try {
  stmt = conn.createStatement();
  query = new StringBuffer();
  where = new StringBuffer();

  query.setLength(0);               첫 쿼리는 초기화 시켜줄 필요없는데.. 그냥 초기화 해줬습니다..
  query.append("SELECT COUNT(SEQ) TOTAL FROM NEWBOARD \n")  쿼리 카운트입니다..
    .append("WHERE SEQ IS NOT NULL \n"); 별 의미 없는 내용의 조건이지만 where을 쓰기 위해 만들어줬습니다..
  query.append(where);
  rs = stmt.executeQuery(query.toString());
  if (rs.next()) {
   totalCount = rs.getString("TOTAL");
  }
  rs.close();

  if (totalCount.equals("0")) {        총 글의 개수가 0이면 등록된 글이 없다를 표시해주고..
%>

 <tr align="center" bgcolor="#FFFFFF" height="30">
  <td colspan="6">등록된 글이 없습니다.</td>
 </tr>
 <tr height="1" bgcolor="#D2D2D2"><td colspan="6"></td></tr>

<%
  } else {                                
한개라도 있으면.. 아래의 쿼리를 실행합니다..
   query.setLength(0);
   query.append("SELECT SEQ, NAME, SUBJECT, CONTENTS, REG_DATE, RNUM \n")
     .append("FROM ( \n")        
요 위에서 RNUM 을 쓴 이유는 이것도 다음 시간에;..
     .append(" SELECT SEQ, NAME, SUBJECT, CONTENTS, REG_DATE, ROWNUM RNUM \n")
     .append(" FROM ( \n")      
요 위에서  ROWNUM RNUM 쓴 이유는 위에 썼으니까;..
     .append("  SELECT SEQ, NAME, SUBJECT, CONTENTS, TO_CHAR(REG_DATE, 'YYYY-MM-DD') REG_DATE \n")    TO_CHAR 를 사용해서 2012-03-09 오전 00:00:00 이라고 나오는 날짜를 2012-03-09 만 나오게 만듭니다..
     .append("  FROM NEWBOARD \n")
     .append("  WHERE SEQ IS NOT NULL \n");
   query.append(where);
   query.append("  ORDER BY REG_DATE DESC \n")
     정렬은 등록역순으로..
     .append(" ) ) \n");
   rs = stmt.executeQuery(query.toString());

   for (int i = 0; rs.next(); i++) {
%>
 <tr height="25" align="center">
  <td>&nbsp;</td>
  <td><%=rs.getString("SEQ") %></td>
  <td><%=rs.getString("SUBJECT") %></td>
  <td><%=rs.getString("NAME") %></td>
  <td><%=rs.getString("REG_DATE") %></td>
  <td>&nbsp;</td>
 <tr height="1" bgcolor="#D2D2D2"><td colspan="6"></td></tr>

<%
   }
  }
%>

 <tr height="1" bgcolor="#82B5DF"><td colspan="6"></td></tr>
</table>

<table width="100%" cellpadding="0" cellspacing="0" border="0">
 <tr><td colspan="4" height="5"></td></tr>
 <tr align="center">
  <td><a href="/newboard/newboard_add.jsp"><img src="이미지주소" border="0" alt="등록"></a></td>
 </tr>
</table>

<%
 } catch( Exception e ) {
  out.println( e.toString() );
 }
%>

결과 화면을 보면요.. 총 글 개수가 0일때.. 값이 없으니.. 등록된 글이 없다고 찍어줍니다..



글을 등록하면 등록된 글이 표시가 됩니다..


참 쉽죠?..

그럼 다음 글은 모든 분들이 기다릴듯한 페이지 관련된 것들을 한번 해보도록 하죠..

오늘의 소스코드입니다..




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