2020. 12. 7. 10:31ㆍ교육과정/KOSMO
키워드 : 방명록 만들기 (입력 / 목록보기 / 수정 / 삭제 / 페이징 / 페이지 이동 화살표)
****
0. 표준 레이어는 5단계가 일반적이나, 이번 실습에서는 3단계 사용 (view, model, service)
BoardInputForm.jsp의 <form> → BoardSave.jsp에서 WriteArticleService.java의 write( ) 호출 |
1. 사용자 입력값을 가지고 다음 화면으로 넘어가도록 스크립트를 작성한다.
(1) <form>에 액션 속성 부여
<form action='BoardSave.jsp' name='frm' method='post'>
(2) <form>의 자식 요소에 name 속성 부여 (BoardDao.java의 변수명과 같게 해야 함)
작성자 : <input type='text' name='writerName'><br/><br/>
제 목 : <input type='text' name='title'><br/><br/>
내 용 : <textarea name='content' rows='10' cols='40'></textarea><br/><br/>
패스워드(수정/삭제시 필요) :
<input type='password' name='password'><br/><br/>
<input type='button' id='btn' value='작성'>
<input type='reset' id='cancel' value='취소'>
(3) "작성" 버튼을 클릭했을 때 전송되도록 <form>에 id부여 및 제이쿼리 작성
<form action='BoardSave.jsp' name='frm' id='frm' method='post'>
$('#btn').click(function(){
$('#frm').submit();
});
2. BoardSave.jsp 에서 이전화면에서 넘어오는 데이터를 받아서 VO인 BoardRec.java에 저장하도록 스크립트 작성
(1) 한글 깨지지 않도록 지정
<% request.setCharacterEncoding("utf-8"); %>
(2) 전 화면의 입력값을 넘겨받아 BoardRec 클래스의 각 멤버 필드에 지정
<jsp:useBean id="rec" class="board.model.BoardRec">
<jsp:setProperty name="rec" property="*" />
</jsp:useBean>
(3) 확인을 위해 BoardRec의 멤버 변수 중 "작성자", "제목"을 화면에 출력하기 (임시)
<jsp:getProperty property="writerName" name="rec"/><br/>
<jsp:getProperty property="title" name="rec"/><br/>
(결과)
3. BoardSave.jsp에서 이전 화면의 사용자 입력값을 BoardDao.java로 전달한다.
(1) BoardSave.jsp에서 Service클래스의 write( ) 함수 호출
<%
WriteArticleService service = WriteArticleService.getInstance();
service.write(rec);
%>
(2) WriteArticleService.java의 write( ) 에서 BoardDao.java의 메소드 2개 호출
public int write( BoardRec rec ) {
BoardDao dao = BoardDao.getInstance();
int groupId = dao.getGroupId();
int article_id = dao.insert(rec);
※※※※※ getGroupId( ) 메소드 : 게시글 입력 전에 그 글의 그룹번호 (group_id) 지정 ※※※※※
① DB에서 시퀀스가 증가하도록 SQL 작성 후 그 값을 받아와서 변수 groupId에 저장 후 리턴한다.
public int getGroupId() throws BoardException {
....
String sql = "SELECT SEQ_GROUP_ID_ARTICLE.nextVal FROM dual";
rs = ps.executeQuery();
while(rs.next()) {
groupId = rs.getInt("nextval");
}
return groupId;
② groupId의 값을 BoardRec.java 클래스의 멤버변수로 저장
rec.setGroupId(groupId);
③ groupId 값을 바탕으로 순서번호(sequence_no)를 지정
→ BoardRec.java 클래스에 순서번호가 저장됨
DecimalFormat dformat = new DecimalFormat("0000000000");
rec.setSequenceNo( dformat.format(groupId) + "999999");
그룹번호 (group_id) : 7 |
순서번호 (sequence_no) : 0000000007999999 |
④ insert( ) 메소드 : DB에 사용자 입력값을 비롯한 데이터 전송
→ article_id는 nextval로 부여한다.
→ group_id와 sequence_no는 WriteArticleService.java의 write( )에서 지정하여 rec에 저장한 값을 가져온다.
→ posting_date는 sysdate로 부여한다.
→ 나머지 값들도 rec에 저장한 값을 가져온다.
public int insert( BoardRec rec ) throws BoardException {
String sql = "INSERT INTO article(article_id, "
+ "group_id, sequence_no, "
+ "posting_date, "
+ "read_count, writer_name, title, content, password) "
+ "VALUES (SEQ_ARTICLE_ID_ARTICLE.nextVal, ?, ?, sysdate, ?,?,?,?,?)";
ps = con.prepareStatement(sql);
ps.setInt(1, rec.getGroupId());
ps.setString(2, rec.getSequenceNo());
ps.setInt(3, rec.getReadCount());
ps.setString(4, rec.getWriterName());
ps.setString(5, rec.getTitle());
ps.setString(6, rec.getContent());
ps.setString(7, rec.getPassword());
int result = ps.executeUpdate();
(결과) DB에 사용자 입력값이 저장됨
4. 데이터 입력 후 페이지 새로고침(F5) 해도 화면이 바뀌지 않는 상태.
즉, 사용자가 다음 화면으로 넘어가지 못하고 동일한 페이지만 보고 있음.
5. 게시물을 작성하면 BoardView.jsp 화면으로 자동으로 넘어가도록 만들기
① WriteArticleService.java에서 수행한 write( )메소드의 결과를 변수 articleId에 담는다.
int articleId = service.write(rec);
② 주소가 바뀌면서 화면이 전환되도록 Redirect 방식을 사용한다.
게시글 번호를 가지고 가라 수 있도록 ? 이후의 쿼리스트링에 변수 articleId를 사용한다.
response.sendRedirect("BoardView.jsp?id=" + articleId);
6. BoardView.jsp 페이지에서 사용자가 작성한 내용이 보이게 하기
① BoardView.jsp 에서 해당 게시물의 게시글 번호값을 얻어와서 변수에 저장
String id = request.getParameter("id");
② ViewAtricleService.java의 getArticleById( ) 메소드를 호출하여 그 게시글번호를 갖는 레코드를 얻어온다.
ViewArticleService service = ViewArticleService.getInstance();
BoardRec rec = service.getArticleById(id);
③ BoardRec.java 클래스에 저장된 데이터를 불러와서 화면을 구성할 수 있도록 HTML 부분을 작성한다.
<td> 제 목 : </td>
<td><%= rec.getTitle() %></td>
<td> 작성자 : </td>
<td><%= rec.getWriterName() %></td>
<td> 작성일자 : </td>
<td><%= rec.getPostingDate() %></td>
<td> 내 용 : </td>
<td><%= rec.getContent() %></td>
④ ViewArticleService.java의 getArticleById( ) 메소드에서는 넘어오는 인자 String id를 Int타입으로 형 변환 후,
BoardDao.java의 selectById( ) 메소드의 인자로 넣어 호출한다.
public BoardRec getArticleById(String id) throws BoardException {
if( id != null ) article_id = Integer.parseInt(id);
BoardDao dao = BoardDao.getInstance();
BoardRec rec = dao.selectById(article_id);
⑤ BoardDao.java의 selectById( ) 메소드에서는 게시글 번호를 인자로 받아 레코드를 검색한다.
결과로 얻어온 ResultSet의 데이터를 BoardRec.java클래스의 멤버변수로 담는다.
public BoardRec selectById(int id) throws BoardException {
....
String sql = "SELECT * FROM article WHERE article_id=?";
ps.setInt(1, id);
rs = ps.executeQuery();
....
while (rs.next()) {
rec.setArticleId(rs.getInt("article_id"));
rec.setGroupId(rs.getInt("group_id"));
rec.setSequenceNo(rs.getString("sequence_no"));
rec.setPostingDate(rs.getString("posting_date"));
rec.setReadCount(rs.getInt("read_count"));
rec.setWriterName(rs.getString("writer_name"));
rec.setTitle(rs.getString("title"));
rec.setContent(rs.getString("content"));
( 결과 ) 작성한 글 내용을 바로 확인할 수 있다.
⑥ 게시글 번호에 해당되는 현재 시퀀스 값을 얻어와서 리턴한다.
해당되는 글이 없을 경우에는 SQL 결과가 없게 되므로, if문을 수행하지 않고 -1을 리턴한다.
stmt = con.createStatement();
String sqlSeq = "SELECT SEQ_ARTICLE_ID_ARTICLE.currval as articleId FROM dual"; // currval : 현재값 가져오기
rs = stmt.executeQuery(sqlSeq);
if(rs.next()) {
return rs.getInt("articleId");
}
return -1;
→ 하나의 메소드 안에서 2개의 SQL을 전송하기 위해 각기 다른 전송객체인 ps와 stmt를 사용한다.
7. 게시글을 볼 때 조회수 1 증가시키기
① ViewArticleService.java 에서 getArticleById( ) 메소드를 수행할 때,
BoardDao.java의 increaseReadCount( ) 메소드를 호출한다.
dao.increaseReadCount(article_id);
② BoardDao.java의 increaseReadCount( ) 메소드를 작성한다.
public void increaseReadCount( int article_id ) throws BoardException {
String sql = "UPDATE article SET read_count=(read_count+1) WHERE article_id=?";
ps = con.prepareStatement(sql);
ps.setInt(1, article_id);
ps.executeUpdate();
(결과)
8. 목록보기
① BoardList.jsp에서는 새 글이 목록에 보이도록 다음의 스크립트가 필요하다.
<% //웹브라우저가 게시글 목록을 캐싱할 경우 새로운 글이 추가되더라도 새글이 목록에 안 보일 수 있기 때문에 설정
response.setHeader("Pragma","No-cache"); // HTTP 1.0 version
response.setHeader("Cache-Control","no-cache"); // HTTP 1.1 version
response.setHeader("Cache-Control","no-store"); // 일부 파이어폭스 버스 관련
response.setDateHeader("Expires", 1L); // 현재 시간 이전으로 만료일을 지정함으로써 응답결과가 캐쉬되지 않도록 설정
%>
② ListArticleService.java의 getArticleList( ) 메소드를 호출하여 List 타입의 변수 mList에 리턴값을 담는다.
ListArticleService service = ListArticleService.getInstance();
List <BoardRec> mList = service.getArticleList() ;
③ BoardList.jsp의 HTML 부분에 mList의 내용을 가져다가 출력하도록 for 반복문을 사용한다.
<% for(BoardRec rec : mList) { %>
<tr>
<td><%= rec.getArticleId() %></td>
<td><%= rec.getTitle() %></td>
<td><%= rec.getWriterName() %></td>
<td><%= rec.getPostingDate() %></td>
<td><%= rec.getReadCount() %></td>
</tr>
<% } // end of for %>
④ ListArticleService.java의 getArticleList( ) 메소드는 BoardDao.java의 selectList( ) 메소드를 호출하고,
BoardRec 타입의 List를 리턴값으로 가져온다.
List <BoardRec> mList = BoardDao.getInstance().selectList();
⑤ BoardDao.java의 selectList( ) 메소드에서는 내용과 비밀번호를 제외한 레코드를
순서번호(sequence_no)의 역순으로 정렬한 뒤 가져온다.
목록이 비어있지 않을 때는 isEmpty의 Boolean 값을 반대로 바꿔준다.
public List<BoardRec> selectList() throws BoardException {
String sql = "SELECT * FROM article ORDER BY sequence_no DESC";
....
while(rs.next()) {
BoardRec rec = new BoardRec();
rec.setArticleId(rs.getInt("article_id"));
rec.setGroupId(rs.getInt("group_id"));
rec.setSequenceNo(rs.getString("sequence_no"));
rec.setPostingDate(rs.getString("posting_date"));
rec.setReadCount(rs.getInt("read_count"));
rec.setWriterName(rs.getString("writer_name"));
rec.setTitle(rs.getString("title"));
mList.add(rec);
isEmpty = false;
⑥ selecList( ) 의 리턴값인 mList는 ListArticleService.java의 getArticleList( )를 거쳐 BoardList.jsp에 도달한다.
mList의 데이터로 화면을 그리게 된다.
9. 제목을 클릭하면 해당 게시물 페이지로 이동하기
① <a> 태그로 하이퍼 링크를 걸어주되 그 글의 게시물 번호를 파라미터로 가져가도록 쿼리스트링을 작성
<a href="BoardView.jsp?id=<%= rec.getArticleId() %>"><%= rec.getTitle() %></a>
10. "삭제하기" 클릭시 암호 입력 후 글 삭제되도록 DB연동하기
(1) BoardView.jsp 의 "삭제하기" 텍스트에 <a>태그로 BoardDeleteForm.jsp에 연결될 때,
게시글 번호를 파라미터로 가져가는 하이퍼링크를 만든다.
<a href="BoardDeleteForm.jsp?id=<%= rec.getArticleId() %>">삭제하기</a>
(2) 주소를 통해 넘겨받은 게시글 번호를 BoardDeleteForm.jsp 에서 받아서 변수 id에 저장한다.
String id = request.getParameter("id");
(3) <form>에서 다음 페이지로 넘겨주는 파라미터에 id와 password가 포함 되도록,
게시물 번호를 hidden 타입으로 <form> 안에 넣는다.
<input type='hidden' name='id' value='<%= id %>' />
(4) 이전 페이지에서 넘어오는 삭제할 레코드의 id와 password 값을 BoardDelete.jsp 에서 받아서 변수에 저장한다.
String id = request.getParameter("id");
String password = request.getParameter("password");
(5) DeleteArticleService.java의 delete( ) 메소드를 호출하면서 id와 password를 인자로 넘겨준다.
int result = 0;
result = DeleteArticleService.getInstance().delete(id, password);
(6) DeleteArticleService.java의 delete( ) 메소드에서는 BoardDao.java의 delete( ) 메소드를 호출한다.
int result = BoardDao.getInstance().delete(article_id, password);
(7) BoardDao.java 의 delete( ) 메소드를 작성한다.
public int delete( int article_id, String password ) throws BoardException {
String sql = "DELETE FROM article WHERE article_id=? AND password=?";
ps = con.prepareStatement(sql);
ps.setInt(1, article_id);
ps.setString(2, password);
int result = ps.executeUpdate();
return result;
(8) 삭제 결과가 int 타입으로 리턴되어 BoardDelete.jsp의 if문을 수행하고 화면에 결과를 보여준다.
<% if( result != 0) { %>
글을 삭제하였습니다.
<% } else { %>
삭제가 실패되었습니다.
<% } %>
(결과)
11. "수정하기" 클릭시 수정 페이지로 이동하고, 사용자 입력값을 DB에 반영하기
(1) BoardView.jsp 의 "수정하기" 텍스트에 <a>태그로 BoardModifyForm.jsp에 연결될 때,
게시글 번호를 파라미터로 가져가는 하이퍼링크를 만든다.
<a href="BoardModifyForm.jsp?id=<%= rec.getArticleId() %>">수정하기</a>
(2) 주소를 통해 넘겨받은 게시글 번호를 BoardModifyForm.jsp 에서 받아서 변수 id에 저장한다.
String id = request.getParameter("id");
(3) ViewArticleService.java의 getArticleById( ) 메소드를 호출하여 게시글 번호의 레코드를 가져온다.
ViewArticleService service = ViewArticleService.getInstance();
BoardRec rec = service.getArticleById(id);
(4) 가져온 레코드의 데이터가 HTML 부분에 들어가도록 스크립트를 작성한다.
① 입력된 데이터가 BoardModify.jsp로 넘어가도록 <form>에 액션 태그 부여
<form action='BoardModify.jsp' name='frm' method='post'>
② 게시글 번호도 <form>에 포함시켜서 가져가도록 hidden 타입으로 스크립트 작성
<input type='hidden' name='id' value='<%= id %>' />
③ 기존 제목 데이터를 <input>의 입력칸에 출력
제 목 : <input type='text' name='title' value='<%= rec.getTitle() %>'><br/><br/>
④ 기존 내용 데이터를 <textarea>의 입력칸에 출력
내 용 : <textarea name='content' rows='10' cols='40'><%= rec.getContent() %></textarea><br/><br/>
(5) 이전 화면의 입력값을 BoardModify.jsp 에서 넘겨받아 한글처리 후 BoardRec.java 클래스의 멤버변수로 지정
<%
request.setCharacterEncoding("utf-8");
%>
<jsp:useBean id="rec" class="board.model.BoardRec">
<jsp:setProperty name="rec" property="*" />
</jsp:useBean>
(6) ModifyArticleService.java 의 update( ) 메소드를 호출
ModifyArticleService service = ModifyArticleService.getInstance();
int result = service.update(rec);
(7) ModifyArticleService.java 의 update( ) 에서 BoardDao.java의 update( ) 메소드 호출
public int update( BoardRec rec ) throws BoardException {
int result = BoardDao.getInstance().update(rec);
return result;
(8) BoardDao.java 의 update( ) 메소드 작성
public int update( BoardRec rec ) throws BoardException {
String sql = "UPDATE article SET title='?', content='?' WHERE article_id=? AND password=?";
ps = con.prepareStatement(sql);
ps.setString(1, rec.getTitle());
ps.setString(2, rec.getContent());
ps.setInt(3, rec.getArticleId());
ps.setString(4, rec.getPassword());
int result = ps.executeUpdate();
return result;
(9) 메소드 수행 결과(업데이트 성공한 행 갯수)가 리턴되어 BoardModify.jsp로 전달
int result = service.update(rec);
(10) 수행 결과인 int값에 따라 화면이 내용이 바뀌도록 if 문 작성
① 게시글 수정이 성공적으로 되었다면 해당 게시물을 보여주는 페이지로 이동
<%
if (result != 0) {
response.sendRedirect("BoardView.jsp?id="+rec.getArticleId());
}
%>
② 게시글 수정이 이루어지지 않았다면 "암호가 잘못 입력되었습니다"를 출력하면서
이전 페이지로 돌아가는 하이퍼링크 생성
<% else { %>
암호가 잘못 입력되었습니다.<br/>
<a href="BoardModifyForm.jsp?id=<%= rec.getArticleId() %>">[돌아가기]</a>
<% } %>
(결과)
12. 페이징 완성하기
(1) BoardDao.java 에서 전체 레코드 수를 검색하는 getTotalcount( ) 메소드를 작성
public int getTotalCount() throws BoardException {
PreparedStatement ps = null;
ResultSet rs = null;
int count = 0;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT count(*) cnt FROM article";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()) {
count = rs.getInt("cnt");
}
return count;
(2) ListArticleService.java 에서 BoardDao.java의 getTotalCount( ) 메소드를 호출하는
함수 getTotalPage( ) 메소드를 작성
public int getTotalPage() throws BoardException {
int totalRecCount = BoardDao.getInstance().getTotalCount();
int temp = (totalRecCount % countPerPage);
if (temp == 0) {
pageTotalCount = (totalRecCount/countPerPage);
} else {
pageTotalCount = (totalRecCount/countPerPage) + 1;
}
return pageTotalCount;
}
(3) BoardList.jsp 에서 ListArticleService.java의 getTotalPage( ) 메소드를 호출
int pageTotalCount = service.getTotalPage();
(4) getTotalPage( ) 메소드의 리턴값인 pageTotalCount를 사용하여
BoardList.jsp 에서 페이지 번호가 표시될 HTML을 만들되,
페이지 번호를 클릭하면 그 값을 파라미터로 가지고 갈 수 있도록 쿼리스트링을 작성한다.
<% for (int i=1; i<=pageTotalCount; i++) { %>
<a href='BoardList.jsp?page=<%= i %>'>[ <%= i %>]</a>
<% } %>
(5) 파라미터로 넘어오는 페이지 번호를 받아주도록 변수를 생성하고 형변환한다.
String pNum = request.getParameter("page");
int pageNo = 1;
if (pNum != null)
pageNo = Integer.parseInt(pNum);
(6) BoardList.jsp 에서 기존에 작성했던 getArticleList( ) 메소드가 pageNo를 인자로 가져가도록 수정
List <BoardRec> mList = service.getArticleList(pageNo);
(7) ListArticleService.java의 getArticleList( ) 메소드가 인자 pageNo를 받아서
변수 firstRow와 endRow를 지정하고, BoardDao.java의 selectList( ) 메소드를 호출 할 때 그 값을 사용
public List <BoardRec> getArticleList(int pageNo) throws BoardException {
/* 페이지번호 시작레코드번호 끝레코드번호
1 1 = 1*10 -9 10 = 1*10
2 11 = 2*10 -9 20 = 2*10
3 21 = 3*10 -9 30 = 3*10
*/
int firstRow = pageNo * countPerPage - 9;
int endRow = pageNo * countPerPage;
List <BoardRec> mList = BoardDao.getInstance().selectList(firstRow, endRow);
return mList;
}
(8) BoardDao.java의 selectList( ) 메소드가 인자 2개를 받아서 수행되도록 수정
public List<BoardRec> selectList(int firstRow, int endRow) throws BoardException {
(9) 페이지에 해당되는 글 목록만 가져오도록 SQL 작성
String sql = "SELECT * FROM article WHERE article_id IN "
+ "(SELECT article_id FROM"
+ "(SELECT rownum as num, article_id FROM"
+ "(SELECT article_id FROM article ORDER BY article_id DESC))"
+ "WHERE (num >=? AND num <=?))"
+ "ORDER BY sequence_no DESC";
(10) 인자로 받아온 값이 SQL의 "?" 에 들어가도록 지정
ps.setInt(1, firstRow);
ps.setInt(2, endRow);
(결과)
13. 첫페이지/마지막페이지로 이동하기 + 이전페이지/다음페이지로 이동하기
(1) BoardList.jsp에서 페이지 번호의 양 옆으로 하이퍼링크가 들어간 화살표 텍스트를 만든다.
<a href="">[◀◀]</a>
<a href="">[◀]</a>
<% for (int i=1; i<=pageTotalCount; i++) { %>
<a href='BoardList.jsp?page=<%= i %>'>[ <%= i %>]</a>
<% } %>
<a href="">[▶]</a>
<a href="">[▶▶]</a>
(2) 각각 이동될 페이지를 href 속성에 넣어준다.
<a href="BoardList.jsp?page=1">[◀◀]</a>
<a href="BoardList.jsp?page=<%= pageNo-1 %>">[◀]</a>
<a href="BoardList.jsp?page=<%= pageNo+1 %>">[▶]</a>
<a href="BoardList.jsp?page=<%= pageTotalCount %>">[▶▶]</a>
(결과)
14. 전체 소스 코드
< 실습 전 압축 파일 >
< BoardInputForm.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판 글쓰기</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="./js/jquery.validate.min.js"></script>
<script type="text/javascript">
$(function(){
$('#btn').click(function(){
// 유효성 검사
$('#frm').validate({
rules : {
writerName : { required : true, maxlength : 20 },
title : { required : true, maxlength : 100 },
content : { required : true, maxlength : 1024 },
password : { required : true, maxlength : 20 }
}
});
$('#frm').submit();
});
})
</script>
</head>
<body>
<!-- 1. 해당 입력칸에 name 부여
2. 폼의 submit (전송) -->
<h4> 게시판 글 쓰기 </h4><br/>
나중에 이쁘게 만드시오 <br/><br/>
<form action='BoardSave.jsp' name='frm' id='frm' method='post'>
작성자 : <input type='text' name='writerName'><br/><br/>
제 목 : <input type='text' name='title'><br/><br/>
내 용 : <textarea name='content' rows='10' cols='40'></textarea><br/><br/>
패스워드(수정/삭제시 필요) :
<input type='password' name='password'><br/><br/>
<input type='button' id='btn' value='작성'>
<input type='reset' id='cancel' value='취소'>
</form>
</body>
</html>
< BoardSave.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.model.*,board.service.*" %>
<%
// 0. 넘겨받는 한글 깨지지 않도록 지정
request.setCharacterEncoding("utf-8");
%>
<!-- 1. 전 화면 입력값을 넘겨받아 BoardRec 클래스의 각 멤버필드에 지정 -->
<% // BoardRec rec = new BoardRec();
// String writer = request.getParameter("writerName");
// rec.setWriterName(writer);
// .....
%>
<jsp:useBean id="rec" class="board.model.BoardRec">
<jsp:setProperty name="rec" property="*" />
</jsp:useBean>
<%
// 2. Service클래스에 write() 함수호출
WriteArticleService service = WriteArticleService.getInstance();
int articleId = service.write(rec);
response.sendRedirect("BoardView.jsp?id=" + articleId);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판글저장</title>
</head>
<body>
<!-- BoardRec의 멤버변수(작성자, 제목) 출력 -->
<jsp:getProperty property="writerName" name="rec"/><br/>
<jsp:getProperty property="title" name="rec"/><br/>
입력되었는지 확인해보시구염...<br/>
만일 안되어도..환장하지 맙시다 !!! ^^<br/><br/>
</body>
</html>
< WriteArticleService.java 소스 코드 >
package board.service;
import java.text.DecimalFormat;
import board.model.*;
public class WriteArticleService {
private static WriteArticleService instance;
public static WriteArticleService getInstance() throws BoardException{
if( instance == null )
{
instance = new WriteArticleService();
}
return instance;
}
public int write( BoardRec rec ) throws BoardException{
BoardDao dao = BoardDao.getInstance();
// 그룹번호(group_id) 지정
int groupId = dao.getGroupId();
rec.setGroupId(groupId);
// 순서번호(sequence_no) 지정
DecimalFormat dformat = new DecimalFormat("0000000000");
rec.setSequenceNo( dformat.format(groupId) + "999999");
/*
그룹번호 (group_id) : 7
순서번호 (sequence_no) : 0000000007999999
*/
// DB에 insert
int article_id = dao.insert(rec);
return article_id;
}
}
< BoardView.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.service.*, board.model.*" %>
<%
// 1. 해당 게시물의 게시글번호값을 얻어온다
String id = request.getParameter("id");
// 2. Service에 getArticleById() 호출하여 그 게시글번호를 갖는 레코드를 검색한다.
ViewArticleService service = ViewArticleService.getInstance();
BoardRec rec = service.getArticleById(id);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 게시글 보기 </title>
</head>
<body>
<h4> 게시판 글 보기 </h4><br/>
<table border="1" bordercolor="red">
<tr>
<td> 제 목 : </td>
<td><%= rec.getTitle() %></td>
</tr>
<tr>
<td> 작성자 : </td>
<td><%= rec.getWriterName() %></td>
</tr>
<tr>
<td> 작성일자 : </td>
<td><%= rec.getPostingDate() %></td>
</tr>
<tr>
<td> 내 용 : </td>
<td><%= rec.getContent() %></td>
</tr>
<tr>
<td colspan="2">
<a href="BoardList.jsp">목록보기</a>
답변하기
<a href="BoardModifyForm.jsp?id=<%= rec.getArticleId() %>">수정하기</a>
<a href="BoardDeleteForm.jsp?id=<%= rec.getArticleId() %>">삭제하기</a>
</td>
</tr>
</table>
</body>
</html>
< ViewArticleService.java 소스 코드 >
package board.service;
import java.util.List;
import board.model.BoardDao;
import board.model.BoardException;
import board.model.BoardRec;
public class ViewArticleService {
private static ViewArticleService instance;
public static ViewArticleService getInstance() throws BoardException{
if( instance == null )
{
instance = new ViewArticleService();
}
return instance;
}
public BoardRec getArticleById(String id) throws BoardException
{
int article_id = 0;
if( id != null ) article_id = Integer.parseInt(id); // 형변환
BoardDao dao = BoardDao.getInstance();
BoardRec rec = dao.selectById(article_id); // 글 번호를 넘겨주면 해당되는 레코드를 줌
dao.increaseReadCount(article_id);
return rec;
}
}
< BoardList.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.model.*, board.service.*" %>
<%@ page import="java.util.List" %>
<% //웹브라우저가 게시글 목록을 캐싱할 경우 새로운 글이 추가되더라도 새글이 목록에 안 보일 수 있기 때문에 설정
response.setHeader("Pragma","No-cache"); // HTTP 1.0 version
response.setHeader("Cache-Control","no-cache"); // HTTP 1.1 version
response.setHeader("Cache-Control","no-store"); // 일부 파이어폭스 버스 관련
response.setDateHeader("Expires", 1L); // 현재 시간 이전으로 만료일을 지정함으로써 응답결과가 캐쉬되지 않도록 설정
%>
<%
String pNum = request.getParameter("page");
int pageNo = 1;
if (pNum != null)
pageNo = Integer.parseInt(pNum);
// Service에 getArticleList()함수를 호출하여 전체 메세지 레코드 검색
ListArticleService service = ListArticleService.getInstance();
int pageTotalCount = service.getTotalPage();
List <BoardRec> mList = service.getArticleList(pageNo);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 게시글 목록 </title>
</head>
<BODY>
<h3> 게시판 목록 </h3>
<table border="1" bordercolor="darkblue">
<tr>
<td> 글번호 </td>
<td> 제 목 </td>
<td> 작성자 </td>
<td> 작성일 </td>
<td> 조회수 </td>
</tr>
<% if( mList.isEmpty() ) { %>
<tr><td colspan="5"> 등록된 게시물이 없습니다. </td></tr>
<% } else { %>
<% for(BoardRec rec : mList) { %>
<tr>
<td><%= rec.getArticleId() %></td>
<td><a href="BoardView.jsp?id=<%= rec.getArticleId() %>"><%= rec.getTitle() %></a></td>
<td><%= rec.getWriterName() %></td>
<td><%= rec.getPostingDate() %></td>
<td><%= rec.getReadCount() %></td>
</tr>
<% } // end of for %>
<% } // end else %>
<tr>
<td colspan="5">
<a href="BoardInputForm.jsp">글쓰기</a>
</td>
</tr>
</table>
<a href="BoardList.jsp?page=1">[◀◀]</a>
<a href="BoardList.jsp?page=<%= pageNo-1 %>">[◀]</a>
<% for (int i=1; i<=pageTotalCount; i++) { %>
<a href='BoardList.jsp?page=<%= i %>'>[ <%= i %>]</a>
<% } %>
<a href="BoardList.jsp?page=<%= pageNo+1 %>">[▶]</a>
<a href="BoardList.jsp?page=<%= pageTotalCount %>">[▶▶]</a>
</BODY>
</HTML>
< ListArticleService.java 소스 코드 >
package board.service;
import java.util.List;
import board.model.BoardDao;
import board.model.BoardException;
import board.model.BoardRec;
public class ListArticleService {
private static ListArticleService instance;
int countPerPage = 10;
int pageTotalCount;
public static ListArticleService getInstance() throws BoardException{
if( instance == null )
{
instance = new ListArticleService();
}
return instance;
}
// 전체 게시글 목록을 얻어옴
public List <BoardRec> getArticleList(int pageNo) throws BoardException
{
/* 페이지번호 시작레코드번호 끝레코드번호
1 1 = 1*10 -9 10 = 1*10
2 11 = 2*10 -9 20 = 2*10
3 21 = 3*10 -9 30 = 3*10
*/
int firstRow = pageNo * countPerPage - 9;
int endRow = pageNo * countPerPage;
List <BoardRec> mList = BoardDao.getInstance().selectList(firstRow, endRow);
return mList;
}
// 전체 게시물 갯수를 구함
public int getTotalPage() throws BoardException {
int totalRecCount = BoardDao.getInstance().getTotalCount();
int temp = (totalRecCount % countPerPage);
if (temp == 0) {
pageTotalCount = (totalRecCount/countPerPage);
} else {
pageTotalCount = (totalRecCount/countPerPage) + 1;
}
return pageTotalCount;
}
}
< BoardDeleteForm.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.service.*, board.model.*" %>
<%
// 1. 삭제할 레코드의 게시글번호 넘겨받기
String id = request.getParameter("id");
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 게시글 삭제하기 </title>
</head>
<body>
<form method="post" action="BoardDelete.jsp">
삭제할 글암호를 입력하세요 <br/>
<input type='hidden' name='id' value='<%= id %>' />
<input type="password" name="password">
<!-- 게시글번호를 다음 페이지로 넘기기 위해 hidden 태그로 지정 -->
<input type="submit" value="삭제하기">
</form>
</body>
</html>
< BoardDelete.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.model.*,board.service.*" %>
<%
// 1. 삭제할 레코드의 게시글번호와 비밀번호를 넘겨받기
String id = request.getParameter("id");
String password = request.getParameter("password");
// 2. Service에 delete() 호출
int result = 0;
result = DeleteArticleService.getInstance().delete(id, password);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 게시글 삭제 </title>
</head>
<body>
<% if( result != 0) { %>
글을 삭제하였습니다.
<% } else { %>
삭제가 실패되었습니다.
<% } %>
<br/><br/>
<a href="BoardList.jsp"> 목록보기 </a>
</body>
</html>
< DeleteArticleService.java 소스 코드 >
package board.service;
import board.model.*;
public class DeleteArticleService {
private static DeleteArticleService instance;
public static DeleteArticleService getInstance() throws BoardException{
if( instance == null )
{
instance = new DeleteArticleService();
}
return instance;
}
public int delete( String id, String password ) throws BoardException{
// DB delete
int article_id = 0;
if( id!=null ) article_id = Integer.parseInt( id );
int result = BoardDao.getInstance().delete(article_id, password);
return result;
}
}
< BoardModifyForm.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.service.*, board.model.*" %>
<%
// 1. 수정할 레코드의 게시글번호를 넘거받기
String id = request.getParameter("id");
// 2. Service에 getArticleById()함수를 호출하여 그 게시글번호의 레코드를 검색
ViewArticleService service = ViewArticleService.getInstance();
BoardRec rec = service.getArticleById(id);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 수정하기</title>
</head>
<body>
<h4> 게시판 글 수정하기 </h4><br/>
<form action='BoardModify.jsp' name='frm' method='post'>
<input type='hidden' name='articleId' value='<%= id %>' />
제 목 : <input type='text' name='title' value='<%= rec.getTitle() %>'><br/><br/>
패스워드(수정/삭제시 필요) :
<input type='password' name='password'><br/><br/>
내 용 : <textarea name='content' rows='10' cols='40'><%= rec.getContent() %></textarea><br/><br/>
<input type='submit' value='수정하기'>
<input type='button' value='목록보기' onclick="window.location='BoardList.jsp'">
</form>
</body>
</html>
< BoardModify.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="board.model.*,board.service.*" %>
<%
// 0. 넘겨받는 데이타의 한글 처리
request.setCharacterEncoding("utf-8");
%>
<!-- 1. 이전 화면의 입력값을 넘겨받아 BoardRec 객체의 각 멤버변수로 지정 -->
<jsp:useBean id="rec" class="board.model.BoardRec">
<jsp:setProperty name="rec" property="*" />
</jsp:useBean>
<%
// 2. Service에 update() 호출하여 레코드 수정
ModifyArticleService service = ModifyArticleService.getInstance();
int result = service.update(rec);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시판글수정</title>
</head>
<body>
<% // 게시글 수정이 성공적으로 되었다면 그 해당 게시글을 보여주는 페이지로 이동하고
// 그렇지 않다면, "암호가 잘못 입력되었습니다"를 출력 %>
<% if (result != 0) {
response.sendRedirect("BoardView.jsp?id="+rec.getArticleId());
} else { %>
암호가 잘못 입력되었습니다.<br/>
<a href="BoardModifyForm.jsp?id=<%= rec.getArticleId() %>">[돌아가기]</a>
<% } %>
</body>
</html>
< ModifyArticleService.jsp 소스 코드 >
package board.service;
import board.model.*;
public class ModifyArticleService {
private static ModifyArticleService instance;
public static ModifyArticleService getInstance() throws BoardException{
if( instance == null )
{
instance = new ModifyArticleService();
}
return instance;
}
public int update( BoardRec rec ) throws BoardException{
// DB update
int result = BoardDao.getInstance().update(rec);
return result;
}
}
< BoardDao.java 소스 코드 >
package board.model;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BoardDao
{
// Single Pattern
private static BoardDao instance;
// DB 연결시 관한 변수
private static final String dbDriver = "oracle.jdbc.driver.OracleDriver";
private static final String dbUrl = "jdbc:oracle:thin:@192.168.0.17:1521:orcl";
private static final String dbUser = "scott";
private static final String dbPass = "tiger";
private Connection con;
//--------------------------------------------
//##### 객체 생성하는 메소드 : 싱글톤 사용 - 다수의 사용자가 접속할 때마다 드라이버를 생성하지 않도록 하기 위함
public static BoardDao getInstance() throws BoardException
{
if( instance == null )
{
instance = new BoardDao();
}
return instance;
}
private BoardDao() throws BoardException
{
try{
/********************************************
1. 오라클 드라이버를 로딩
( DBCP 연결하면 삭제할 부분 )
*/
Class.forName( dbDriver );
}catch( Exception ex ){
throw new BoardException("DB 연결시 오류 : " + ex.toString() );
}
}
//--------------------------------------------
//##### 게시글 입력전에 그 글의 그룹번호를 얻어온다
public int getGroupId() throws BoardException
{
PreparedStatement ps = null;
ResultSet rs = null;
int groupId=1;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT SEQ_GROUP_ID_ARTICLE.nextVal FROM dual";
ps = con.prepareStatement( sql );
rs = ps.executeQuery();
while(rs.next()) {
groupId = rs.getInt("nextval");
}
return groupId;
}catch( Exception ex ){
throw new BoardException("게시판 ) 게시글 입력 전에 그룹번호 얻어올 때 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 게시판에 글을 입력시 DB에 저장하는 메소드
public int insert( BoardRec rec ) throws BoardException
{
/************************************************
*/
ResultSet rs = null;
Statement stmt = null;
PreparedStatement ps = null;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "INSERT INTO article(article_id, group_id, sequence_no, posting_date, read_count, writer_name, title, content, password) "
+ "VALUES (SEQ_ARTICLE_ID_ARTICLE.nextVal, ?, ?, sysdate, ?,?,?,?,?)";
ps = con.prepareStatement(sql);
ps.setInt(1, rec.getGroupId());
ps.setString(2, rec.getSequenceNo());
ps.setInt(3, rec.getReadCount());
ps.setString(4, rec.getWriterName());
ps.setString(5, rec.getTitle());
ps.setString(6, rec.getContent());
ps.setString(7, rec.getPassword());
//
int result = ps.executeUpdate();
System.out.println(result + "행 입력 성공");
////////////////////////////////////////////////////////////////
stmt = con.createStatement();
String sqlSeq = "SELECT SEQ_ARTICLE_ID_ARTICLE.currval as articleId FROM dual"; // currval : 현재값 가져오기
rs = stmt.executeQuery(sqlSeq);
if(rs.next()) {
System.out.println("BoardDao 113line : " + rs.getInt("articleId"));
return rs.getInt("articleId");
}
///////////////////////////////////////////////////////////////
return -1;
}catch( Exception ex ){
throw new BoardException("게시판 ) DB에 입력시 오류 : " + ex.toString() );
} finally{
if( rs != null ) { try{ rs.close(); } catch(SQLException ex){} }
if( stmt != null ) { try{ stmt.close(); } catch(SQLException ex){} }
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 전체 레코드를 검색하는 함수
// 리스트에 보여줄거나 필요한 컬럼 : 게시글번호, 그룹번호, 순서번호, 게시글등록일시, 조회수, 작성자이름, 제목
// ( 내용, 비밀번호 제외 )
// 순서번호(sequence_no)로 역순정렬
public List<BoardRec> selectList(int firstRow, int endRow) throws BoardException
{
PreparedStatement ps = null;
ResultSet rs = null;
List<BoardRec> mList = new ArrayList<BoardRec>();
boolean isEmpty = true;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// String sql = "SELECT * FROM article ORDER BY sequence_no DESC";
String sql = "SELECT * FROM article WHERE article_id IN "
+ "(SELECT article_id FROM"
+ "(SELECT rownum as num, article_id FROM"
+ "(SELECT article_id FROM article ORDER BY article_id DESC))"
+ "WHERE (num >=? AND num <=?))"
+ "ORDER BY sequence_no DESC";
ps = con.prepareStatement(sql);
ps.setInt(1, firstRow);
ps.setInt(2, endRow);
rs = ps.executeQuery();
while(rs.next()) {
BoardRec rec = new BoardRec();
rec.setArticleId(rs.getInt("article_id"));
rec.setGroupId(rs.getInt("group_id"));
rec.setSequenceNo(rs.getString("sequence_no"));
rec.setPostingDate(rs.getString("posting_date"));
rec.setReadCount(rs.getInt("read_count"));
rec.setWriterName(rs.getString("writer_name"));
rec.setTitle(rs.getString("title"));
mList.add(rec);
isEmpty = false;
}
if( isEmpty ) return Collections.emptyList();
return mList;
}catch( Exception ex ){
throw new BoardException("게시판 ) DB에 목록 검색시 오류 : " + ex.toString() );
} finally{
if( rs != null ) { try{ rs.close(); } catch(SQLException ex){} }
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 게시글번호에 의한 레코드 검색하는 함수
// 비밀번호 제외하고 모든 컬럼 검색
public BoardRec selectById(int id) throws BoardException
{
PreparedStatement ps = null;
ResultSet rs = null;
BoardRec rec = new BoardRec();
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT * FROM article WHERE article_id=?";
ps = con.prepareStatement(sql);
ps.setInt(1, id);
rs = ps.executeQuery();
while(rs.next()) {
rec.setArticleId(rs.getInt("article_id"));
rec.setGroupId(rs.getInt("group_id"));
rec.setSequenceNo(rs.getString("sequence_no"));
rec.setPostingDate(rs.getString("posting_date"));
rec.setReadCount(rs.getInt("read_count"));
rec.setWriterName(rs.getString("writer_name"));
rec.setTitle(rs.getString("title"));
rec.setContent(rs.getString("content"));
}
return rec;
}catch( Exception ex ){
throw new BoardException("게시판 ) DB에 글번호에 의한 레코드 검색시 오류 : " + ex.toString() );
} finally{
if( rs != null ) { try{ rs.close(); } catch(SQLException ex){} }
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//##### 전체 레코드 수를 검색
public int getTotalCount() throws BoardException {
PreparedStatement ps = null;
ResultSet rs = null;
int count = 0;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT count(*) cnt FROM article";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()) {
count = rs.getInt("cnt");
}
return count;
}catch( Exception ex ){
throw new BoardException("게시판 ) 전체 레코드 수 검색시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 게시글 보여줄 때 조회수 1 증가
public void increaseReadCount( int article_id ) throws BoardException
{
PreparedStatement ps = null;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "UPDATE article SET read_count=(read_count+1) WHERE article_id=?";
ps = con.prepareStatement(sql);
ps.setInt(1, article_id);
ps.executeUpdate();
}catch( Exception ex ){
throw new BoardException("게시판 ) 게시글 볼 때 조회수 증가시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 게시글 수정할 때
// ( 게시글번호와 패스워드에 의해 수정 )
public int update( BoardRec rec ) throws BoardException
{
PreparedStatement ps = null;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "UPDATE article SET title=?, content=? WHERE article_id=? AND password=?";
ps = con.prepareStatement(sql);
ps.setString(1, rec.getTitle());
ps.setString(2, rec.getContent());
ps.setInt(3, rec.getArticleId());
ps.setString(4, rec.getPassword());
int result = ps.executeUpdate();
return result; // 나중에 수정된 수를 리턴하시오.
}catch( Exception ex ){
throw new BoardException("게시판 ) 게시글 수정시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//--------------------------------------------
//##### 게시글 삭제할 때
// ( 게시글번호와 패스워드에 의해 삭제 )
public int delete( int article_id, String password ) throws BoardException
{
PreparedStatement ps = null;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "DELETE FROM article WHERE article_id=? AND password=?";
ps = con.prepareStatement(sql);
ps.setInt(1, article_id);
ps.setString(2, password);
int result = ps.executeUpdate();
return result; // 나중에 수정된 수를 리턴하시오.
}catch( Exception ex ){
throw new BoardException("게시판 ) 게시글 수정시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
//----------------------------------------------------
//##### 부모레코드의 자식레코드 중 마지막 레코드의 순서번호를 검색
// ( 제일 작은 번호값이 마지막값임)
public String selectLastSequenceNumber( String maxSeqNum, String minSeqNum ) throws BoardException
{
PreparedStatement ps = null;
ResultSet rs = null;
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT min(sequence_no) as minseq FROM article WHERE sequence_no < ? AND sequence_no >= ?";
ps = con.prepareStatement( sql );
ps.setString(1, maxSeqNum);
ps.setString(2, minSeqNum);
rs = ps.executeQuery();
if( !rs.next()) {
return null;
}
return rs.getString("minseq");
}catch( Exception ex ){
throw new BoardException("게시판 ) 부모와 연관된 자식 레코드 중 마지막 순서번호 얻어오기 : " + ex.toString() );
} finally{
if( rs != null ) { try{ rs.close(); } catch(SQLException ex){} }
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
}