2020. 12. 4. 14:21ㆍ교육과정/KOSMO
키워드 : 방명록 만들기 (입력 / 목록보기 / 삭제 / 페이징)
****
View단으로 지칭 (Front-end) | jsp / js / jquery / css / images |
Model단로 지칭 (Back-end) | java / JDBC |
0. 시작 화면은 insertMessage.jsp
※ 전체적인 흐름
: 화면에 데이터 입력 ------- (table)---------> DB에 저장
※ table의 구조
pk(seq) | name | password | message |
1. 화면의 내용이 들어갈 DB를 구성한다.
CREATE table GuestTB (
message_id number, // 메세지번호 PK 자동증가수
guest_name varchar2(10) NOT NULL, // 손님이름
password varchar2(10) NOT NULL, // 비밀번호
message varchar2(1024) NOT NULL, // 메세지
CONSTRAINT pk_GuestTB_message_id PRIMARY KEY (message_id)
);
CREATE SEQUENCE seq_guestTb_messageId;
2. src - guest.model 패키지 내에 Message.java 클래스 생성 (오류가 모두 사라짐)
3. insertMessage.jsp의 <form>에서 input의 name을 참고하여 Message.java에 접근지정자를 private으로 하여 변수를 만든다.
public class Message {
private int id; // 글번호
private String guestName; // 사용자명
private String password; // 사용자암호
private String message; // 사용자메세지
}
4. 상단 메뉴 - Source - Generate Getters and Setters - 변수 모두에 대해 setter getter 생성
상단 메뉴 - Source - Generate Constructors from Superclass - 기본 생성자 생성
상단 메뉴 - Source - Generate Constructor using Fields - 변수 모두를 인자로 갖는 생성자함수 생성
public Message() {
super();
}
public Message(int id, String guestName, String password, String message) {
super();
this.id = id;
this.guestName = guestName;
this.password = password;
this.message = message;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
....
....
<<<<<<<<<< [메세지 남기기] 와 관련된 작업 시작!! >>>>>>>>>>
5. 화면에서 버튼을 클릭해도 데이터가 넘어가지 않으므로 submit()을 적용시켜준다.
$('#btn').click(function(){
$('#frm').submit();
});
→ 데이터 입력 후 클릭하면 화면 넘어가짐
→ 데이터 넘어가기 전 단계에서 유효성 검사를 추가할 수 있다. (validate 플러그인 활용)
$('#btn').click(function(){
$('#frm').validate({
rules : {
guestName : { required : true, maxlength : 10 },
paasword : { required : true, maxlength : 10 },
message : { required : true, maxlength : 1024 }
}
});
$('#frm').submit();
});
6. WriteMessageService.java의 존재 이유
: 그림에서 위의 3개는 View / 아래 2개는 Model인 상황에서
view에는 only 화면과 관련된 코드만 작성하고,
Dao에는 JDBC를 위한 직접적인 코드만 작성하려면,
그 외의 다른 코드를 입력하기 위해 만들어둔 별도의 java 파일이 필요하고 (ex : 목록검색)
그 중 하나가 WriteMessageService.java이다.
7. saveMessage.jsp에서는 3가지 스크립트를 작성한다.
(insertMessage.jsp에서 넘어온 입력값을 model로 전달하기 때문)
→ 한글처리 / 화면의 입력값을 Message.java로 전달
/ WriteMessageService.java의 함수 호출
데이터의 전달 과정 :
insertMessage.jsp 의 <form> →
① saveMessage.jsp 의 <jsp:useBean>
→ guest.model.Message.java에 값 저장
② saveMessage.jsp 의 WriteMessageService.getInstance().write(m) ;
→ WriteMessageService.java 의 write( ) 호출하며 데이터가 들어있는 m(Message 클래스의 객체) 전달
<% request.setCharacterEncoding("utf-8"); %>
<jsp:useBean id="m" class="guest.model.Message">
<jsp:setProperty name="m" property="*" />
</jsp:useBean>
<% WriteMessageService.getInstance().write(m); %>
8. WriteMessageService.java에서는 넘어온 데이터를 DB와 연동되는 MessageDao.java로 전송한다.
→ MessageDao.java의 insert( ) 로 데이터가 들어있는 rec(Message 클래스의 객체) 전달
public void write( Message rec ) throws MessageException{
MessageDao mDao = MessageDao.getInstance();
mDao.insert(rec);
}
MessageDao.java에서는 데이터가 들어있는 rec(Message클래스의 객체)을 인자로 받아 insert()를 수행한다.
→ JDBC 연동 및 DB에 데이터를 전송하는 SQL 수행
public void insert(Message rec) throws MessageException {
....
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "INSERT INTO GuestTB (message_id, guest_name, password, message) "
+ "VALUES (seq_guestTb_messageId.nextval ,?,?,?)";
ps = con.prepareStatement( sql );
ps.setString(1, rec.getGuestName());
ps.setString(2, rec.getPassword());
ps.setString(3, rec.getMessage());
int result = ps.executeUpdate();
(결과) 버튼 클릭시 DB에 사용자 입력값이 저장됨
< 데이터 입력 도식화 >
<<<<<<<<<< [목록보기] 과 관련된 작업 시작!! >>>>>>>>>>
9. saveMessage.jsp에서 [목록보기] 클릭시 listMessage.jsp 페이지로 이동하기 위한 하이퍼링크를 만든다.
<a href='listMessage.jsp'> [ 목록보기 ] </a>
10. listMessage.jsp 에서 DB에 저장된 데이터를 List에 담아 화면에 출력한다.
listMessage.jsp → ListMessageService.java → MessageDao.java
→ ListMessageService.java → listMessage.jsp
데이터의 전달 과정 :
① listMessage.jsp → ListMessageService.java의 getMessageList()를 호출
List <Message> mList = ListMessageService.getInstance().getMessageList();
② ListMessageService.java → MessageDao의 selectList()를 호출
public List <Message> getMessageList(int pageNo) throws MessageException{
List <Message> mList = MessageDao.getInstance().selectList();
return mList;
}
③ MessageDao.java의 selectList() 함수는 수행 결과로 mList (Message 타입의 List)를 리턴한다.
public List<Message> selectList() throws MessageException {
....
try{
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
String sql = "SELECT * FROM GuestTB";
ps = con.prepareStatement( sql );
rs = ps.executeQuery();
while(rs.next()) {
Message temp = new Message();
temp.setId((rs.getInt("message_id")));
temp.setGuestName(rs.getString("guest_name"));
temp.setMessage(rs.getString("message"));
mList.add(temp);
isEmpty = false;
}
if( isEmpty ) return Collections.emptyList();
return mList;
④ listMessage.jsp 에서는 리턴받은 mList로 화면을 그리도록 <table> 태그 부분을 작성한다.
→ 동적 테이블로 생성되기 위해 for 반복문 사용
→ Message 클래스에 저장된 데이터를 가리키는 변수명 m을 사용하여 <td> 태그에 들어갈 데이터를 출력
(주의!) <textarea>태그 사이에 공백이 들어가는 것을 방지하기 위해 주석이나 띄어쓰기를 완전히 배제
<table border="1">
<% for(Message m : mList) { %>
<tr>
<td> <%= m.getId() %></td>
<td> <%= m.getGuestName() %></td>
<td> [삭제] </td>
</tr>
<tr>
<td colspan='3'>
<textarea cols=35 rows=3 style="font-family: '돋움', '돋움체'; font-size: 10pt; font-style: normal; line-height: normal; color: #003399;background-color:#D4EBFF;border:1 solid #00009C;"><%= m.getMessage() %></textarea>
</td>
</tr>
<% } // end of for %>
</table>
(결과)
< 목록보기 도식화 >
<<<<<<<<<< [삭제] 와 관련된 작업 시작!! >>>>>>>>>>
11. listMessag.jsp의 하이퍼링크 → deleteMessage.jsp의 <form> → deleteConfirm.jsp 의 delete( ) 메소드 호출
→ deleteMessageService.java 의 delete( ) 메소드 호출 → MessageDao.java 의 delete( ) 메소드 수행
→ 호출시켰던 곳으로 결과값 리턴
① listMessage.jsp의 [삭제] 텍스트에 <a>태그로 하이퍼링크 생성하되, 사용자명을 주소로 가지고 가도록 만들기
→ deleteMessage.jsp로 연결됨
<td><a href="deleteMessage.jsp"> [삭제] </a></td>
<td><a href="deleteMessage.jsp?id=<%= m.getId() %>"> [삭제] </a></td>
② 이전화면에서 넘어오는 글번호(id) 데이터를 deleteMessage.jsp에서도 받아서 변수에 저장한다.
<% String id = request.getParameter("id"); %>
③ "메세지 삭제" 버튼을 누르면 <form>의 사용자 입력값을 가지고 다음 화면(deleteConfirm.jsp)로 넘어가게 된다.
<form action="deleteConfirm.jsp" method="post">
암호 : <input type="password" name="password" />
<input type="submit" value="메세지 삭제"/>
</form>
→ 글 번호도 <form>에 포함시켜 가지고 가도록 스크립트를 수정한다.
(데이터가 넘어가는지 확인하기 위해 임시로 전송방식을 get으로 바꾼다.)
<form action="deleteConfirm.jsp" method="get">
<input type='hidden' name='id' value='<%= id %>' />
암호 : <input type="password" name="password" />
<input type="submit" value="메세지 삭제"/>
</form>
④ deleteConfirm.jsp에서는 이전 화면에서 넘어오는 id와 password 데이터를 받아 변수에 저장한다.
String id = request.getParameter("id");
String password = request.getParameter("password");
⑤ id와 password 데이터를 인자로 하여 DeleteMessageService.java의 의 delete( ) 메소드를 호출한다.
이 때, DeleteMessageService.java의 생성자함수는 싱글톤패턴이라서
public static인 getInstance( ) 메소드를 통해 객체 생성하고 메소드를 호출하게 된다.
int delCnt = 0;
delCnt = DeleteMessageService.getInstance().delete(id, password);
public class DeleteMessageService {
private static DeleteMessageService instance;
public static DeleteMessageService getInstance() throws MessageException {
if( instance == null ) {
instance = new DeleteMessageService();
}
return instance;
}
→ delete( ) 메소드에서는 인자 2개를 받아 MessageDao.java의 delete( ) 메소드를 수행하고
그 결과를 리턴받는다.
(Dao의 메소드로 int값을 넘겨주기 위해,
DeleteMessageService.java의 delete( ) 에 첫번째 인자가 존재하면 그 값을 parseInt 시켜준다.)
public int delete( String messageId, String password ) throws MessageException {
int mId = 0;
if( messageId != null) mId = Integer.parseInt(messageId);
MessageDao mDao = MessageDao.getInstance();
return mDao.delete(mId, password);
}
⑥ MessageDao.java에서는 2개의 인자를 받아 delete( ) 메소드를 수행하여 DB에서 데이터를 삭제한다.
→ n행 성공여부를 결과로 받으므로 그 int값을 메소드가 호출된 곳으로 리턴한다.
public int delete( int messageId, String password ) throws MessageException {
int result = 0;
....
try{
....
String sql = "DELETE FROM GuestTB WHERE message_id=? AND password=?";
ps = con.prepareStatement( sql );
ps.setInt(1, messageId);
ps.setString(2, password);
result = ps.executeUpdate();
return result;
⑦ deleteConfirm.jsp에서는 메소드 수행 결과인 int값에 따라 화면에 출력할 메세지를 결정한다.
<% if( delCnt == 0 ) { %>
삭제할 메세지가 존재하지 않거나 비밀번호가 올바르지 않습니다.
<% } else { %>
메세지를 삭제하였습니다.
<% } %>
< 삭제 도식화 >
<<<<<<<<<< [페이징] 과 관련된 작업 시작!! >>>>>>>>>>
12. 목록보기에 모든 글이 조회되고 있으므로 특정 갯수만 한 화면에 출력되고,
나머지는 다음 페이지로 넘어가도록 만들어야 한다.
이를 위해, 전체 글 갯수를 구하고, 페이지 버튼이 작동하도록 만든다.
13. MessageDao.java 의 getTotalCount( ) → listMessage.jsp 에서 메소드 호출
→ ListMessageService.java 의 getMessageList( ) → MessageDao.java의 selectList( )
→ ListMessageService.java 의 getTotalPage( ) → MessageDao.java의 getTotalCount( )
① MessageDao.java에서 전체 글 갯수를 알기 위한 getTotalCount( ) 메소드를 작성한다.
→ ResultSet은 첫줄보다 앞을 우선적으로 가리키고 있기 때문에 첫 줄로 가리키기 위해 next( )를 한 번 사용
→ count(*)를 통해 얻어온 전체 글 갯수를 변수 count에 담아서 리턴한다.
public int getTotalCount() throws MessageException{
....
ResultSet rs = null;
int count = 0;
try{
....
String sql = "SELECT count(*) cnt FROM GuestTB";
ps = con.prepareStatement( sql );
rs = ps.executeQuery();
while(rs.next()) {
count = rs.getInt("cnt");
}
return count;
② listMessage.jsp에서 ListMessageService.java 의 getTotalPage( ) 메소드를 호출한다.
결과로 리턴되는 값을 변수 totalPageCount에 저장한다.
ListMessageService.java의 getTotalPage( ) 메소드를 작성한다.
int totalPageCount = ListMessageService.getInstance().getTotalPage();
public int getTotalPage() throws MessageException {
totalRecCount = MessageDao.getInstance().getTotalCount();
int temp = (totalRecCount % countPerPage);
if (temp == 0) {
pageTotalCount = (totalRecCount/countPerPage);
} else {
pageTotalCount = (totalRecCount/countPerPage) + 1;
}
return pageTotalCount;
}
→ ListMessageService.java에서 호출해야 할 메소드가 2개가 되는 것이므로 객체 생성과 각각의 함수 호출을 보기 편하도록 수정해준다.
List <Message> mList = ListMessageService.getInstance().getMessageList()
int totalPageCount = ListMessageService.getInstance().getTotalPage();
ListMessageService service = ListMessageService.getInstance();
int totalPageCount = service.getTotalPage();
List <Message> mList = service.getMessageList();
③ ListMessageService.java의 getTotalPage( ) 메소드를 작성한다.
getTotalPage( ) 에서는 ①에서 작성한 MessageDao.java의 getTotalCount( ) 메소드를 호출하고
리턴값(전체 글 갯수)를 변수 totalRecCount에 담는다.
글 갯수에 따라 몇 페이지까지 만들지 결정하여 변수 pageTotalCount에 담고 listMessage.jsp로 리턴한다.
public int getTotalPage() throws MessageException {
totalRecCount = MessageDao.getInstance().getTotalCount();
int temp = (totalRecCount % countPerPage);
if (temp == 0) {
pageTotalCount = (totalRecCount/countPerPage);
} else {
pageTotalCount = (totalRecCount/countPerPage) + 1;
}
return pageTotalCount;
}
④ listMessage.jsp 의 body에 페이지가 표시될 곳을 작성한다.
<% for (int i=1; i<=totalPageCount; i++) { %>
[ <%= i %>]
<% } %>
⑤ 페이지를 나타내는 글씨에 <a>태그로 하이퍼링크를 만든다.
<a href='listMessage.jsp'>[ <%= i %>]</a>
⑥ 클릭한 숫자에 해당되는 페이지로 넘어가도록 <a>태그를 수정한다.
<a href='listMessage.jsp?page=<%= i %>'>[ <%= i %>]</a>
⑦ 주소창을 통해 넘어오는 페이지 값을 받아줄 변수를 만든다.
String pNum = request.getParameter("page");
⑧ 페이지를 클릭한 후에야 pNum의 값이 존재하게 되므로 그 이전까지는 pNum = null이다.
따라서, 클릭하기 전에 1페이지를 보여주는 것이 기본 설정이 되게 하기 위한 변수 pageNo를 만든다.
int pageNo = 1;
⑨ 페이지를 클릭하면 그 값으로 변수 pageNo가 바뀌도록 스크립트를 작성한다.
if (pNum != null)
pageNo = Integer.parseInt(pNum);
⑩ ListMessageService.java의 getMessageList( ) 메소드가 페이지값을 인자로 받아가도록 수정한다.
List <Message> mList = service.getMessageList(pageNo);
⑪ ListMessageService.java의 getMessageList( ) 메소드가 인자를 받고,
MessageDao.java 의 seletlist( ) 메소드를 호출 할 때 2개의 인자를 넘겨주도록 수정한다.
pageNo (페이지 번호) | firstRow (시작 레코드 번호) | endRow (끝 레코드 번호) |
1 | 1 | 3 |
2 | 4 | 6 |
3 | 7 | 9 |
4 | 10 | 12 |
private int countPerPage = 3; // 한페이지당 레코드 수
public List <Message> getMessageList(int pageNo) throws MessageException {
int firstRow = pageNo * countPerPage - 2;
int endRow = pageNo * countPerPage;
List <Message> mList = MessageDao.getInstance().selectList(firstRow, endRow);
return mList;
}
⑫ MessageDao.java 의 selectList( ) 메소드에서 조건에 맞는 데이터만 가져오도록 SQL을 수정한다.
SELECT * FROM GuestTB WHERE message_id IN
(SELECT message_id FROM
(SELECT rownum as num, message_id FROM
(SELECT message_id FROM GuestTB ORDER BY message_id DESC))
WHERE (num >=4 AND num <=6))
ORDER BY message_id DESC;
※ 페이지에 해당하는 데이터만 가져오는 SQL 만드는 과정
-- [1] 일련번호 검색
SELECT message_id FROM GuestTB;
-- [2] 컬럼을 기준으로 정렬
SELECT message_id FROM GuestTB ORDER BY message_id DESC;
-- [3] 기존컬럼을 정렬 후 그 결과에서 rownum 출력 - FROM에 [2] 대입
SELECT rownum as num, message_id FROM
(SELECT message_id FROM GuestTB ORDER BY message_id DESC);
-- [4] 해당하는 rownum을 이용하여 원하는 순번 출력 - FROM에 [3] 대입 후 WHERE절 작성
SELECT message_id FROM
(SELECT rownum as num, message_id FROM
(SELECT message_id FROM GuestTB ORDER BY message_id DESC))
WHERE (num >=4 AND num <=6);
-- [5] 해당하는 rownum의 전체 레코르 출력 - IN에 [4] 대입 후 id로 내림차순 정렬
SELECT * FROM GuestTB WHERE message_id IN
(SELECT message_id FROM
(SELECT rownum as num, message_id FROM
(SELECT message_id FROM GuestTB ORDER BY message_id DESC))
WHERE (num >=4 AND num <=6))
ORDER BY message_id DESC;
⑬ 페이지를 클릭하면 pageNo의 값이 바뀌고,
pageNo의 값에 따라 몇 번째 글부터 몇 번째 글까지 화면에 보여줄지 결정된다.
결정된 값에 따라 DB에서 데이터를 가져오고 화면을 그린다.
< 페이징 도식화 >
14. "글쓰기" 텍스트에 <a>태그로 insertMessage.jsp 페이지로 넘어가도록 스크립트를 작성한다.
<a href='insertMessage.jsp'>글쓰기</a>
15. 전체 소스 코드
< 실습 전 전체 압축 파일 >
< 실습 후 >
< Message.java 소스 코드 >
package guest.model;
public class Message {
private int id; // 글번호
private String guestName; // 사용자명
private String password; // 사용자암호
private String message; // 사용자메세지
public Message() {
super();
}
public Message(int id, String guestName, String password, String message) {
super();
this.id = id;
this.guestName = guestName;
this.password = password;
this.message = message;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getGuestName() {
return guestName;
}
public void setGuestName(String guestName) {
this.guestName = guestName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
< MessageDao.java 소스 코드 >
package guest.model;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MessageDao {
// Single Pattern
private static MessageDao 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 = "hr";
private static final String dbPass = "hr";
//--------------------------------------------
//##### 객체 생성하는 메소드
public static MessageDao getInstance() throws MessageException
{
if( instance == null )
{
instance = new MessageDao();
}
return instance;
}
private MessageDao() throws MessageException
{
try{
/********************************************
1. 오라클 드라이버를 로딩
( DBCP 연결하면 삭제할 부분 )
*/
Class.forName( dbDriver );
}catch( Exception ex ){
throw new MessageException("방명록 ) DB 연결시 오류 : " + ex.toString() );
}
}
/*
* 메세지를 입력하는 함수
*/
public void insert(Message rec) throws MessageException
{
Connection con = null;
PreparedStatement ps = null;
try{
// 1. 연결객체(Connection) 얻어오기
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// 2. sql 문장 만들기
String sql = "INSERT INTO GuestTB (message_id, guest_name, password, message) "
+ "VALUES (seq_guestTb_messageId.nextval ,?,?,?)";
// 3. 전송객체 얻어오기
ps = con.prepareStatement( sql );
ps.setString(1, rec.getGuestName());
ps.setString(2, rec.getPassword());
ps.setString(3, rec.getMessage());
// 4. 전송하기
int result = ps.executeUpdate();
System.out.println(result + "행 성공");
}catch( Exception ex ){
throw new MessageException("방명록 ) DB에 입력시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
/*
* 메세지 목록 전체를 얻어올 때
*/
public List<Message> selectList() throws MessageException
{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Message> mList = new ArrayList<Message>();
boolean isEmpty = true;
try{
// 1. 연결객체(Connection) 얻어오기
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// 2. sql 문장 만들기
String sql = "SELECT * FROM GuestTB";
// 3. 전송객체 얻어오기
ps = con.prepareStatement( sql );
// 4. 전송하기
rs = ps.executeQuery();
System.out.println(rs);
while(rs.next()) {
Message temp = new Message();
temp.setId((rs.getInt("message_id")));
temp.setGuestName(rs.getString("guest_name"));
temp.setMessage(rs.getString("message"));
mList.add(temp);
isEmpty = false;
}
if( isEmpty ) return Collections.emptyList();
return mList;
}catch( Exception ex ){
throw new MessageException("방명록 ) 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 List<Message> selectList(int firstRow, int endRow) throws MessageException
{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<Message> mList = new ArrayList<Message>();
boolean isEmpty = true;
try{
// 1. 연결객체(Connection) 얻어오기
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// 2. sql 문장 만들기
String sql = "SELECT * FROM GuestTB WHERE message_id "
+ "IN (SELECT message_id FROM (SELECT rownum as num, message_id "
+ "FROM (SELECT message_id FROM GuestTB ORDER BY message_id DESC))"
+ "WHERE (num >=? AND num <=?)) ORDER BY message_id DESC";
// 3. 전송객체 얻어오기
ps = con.prepareStatement( sql );
ps.setInt(1, firstRow);
ps.setInt(2, endRow);
// 4. 전송하기
rs = ps.executeQuery();
System.out.println(rs);
while(rs.next()) {
Message temp = new Message();
temp.setId((rs.getInt("message_id")));
temp.setGuestName(rs.getString("guest_name"));
temp.setMessage(rs.getString("message"));
mList.add(temp);
isEmpty = false;
}
if( isEmpty ) return Collections.emptyList();
return mList;
}catch( Exception ex ){
throw new MessageException("방명록 ) 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 MessageException{
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
int count = 0;
try{
// 1. 연결객체(Connection) 얻어오기
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// 2. sql 문장 만들기
String sql = "SELECT count(*) cnt FROM GuestTB";
// 3. 전송객체 얻어오기
ps = con.prepareStatement( sql );
// 4. 전송하기
rs = ps.executeQuery();
System.out.println(rs);
while(rs.next()) {
count = rs.getInt("cnt");
}
return count;
}catch( Exception ex ){
throw new MessageException("방명록 ) 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 delete( int messageId, String password ) throws MessageException
{
int result = 0;
Connection con = null;
PreparedStatement ps = null;
try{
// 1. 연결객체(Connection) 얻어오기
con = DriverManager.getConnection( dbUrl, dbUser, dbPass );
// 2. sql 문장 만들기
String sql = "DELETE FROM GuestTB WHERE message_id=? AND password=?";
// 3. 전송객체 얻어오기
ps = con.prepareStatement( sql );
ps.setInt(1, messageId);
ps.setString(2, password);
// 4. 전송하기
result = ps.executeUpdate();
System.out.println(result + "행 삭제 성공");
return result;
}catch( Exception ex ){
throw new MessageException("방명록 ) DB에 삭제시 오류 : " + ex.toString() );
} finally{
if( ps != null ) { try{ ps.close(); } catch(SQLException ex){} }
if( con != null ) { try{ con.close(); } catch(SQLException ex){} }
}
}
}
< WriteMessageService.java 소스 코드 >
package guest.service;
import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;
public class WriteMessageService {
private static WriteMessageService instance;
public static WriteMessageService getInstance() throws MessageException
{
if( instance == null )
{
instance = new WriteMessageService();
}
return instance;
}
private WriteMessageService()
{
}
public void write( Message rec ) throws MessageException
{
MessageDao mDao = MessageDao.getInstance();
mDao.insert(rec);
}
}
< ListMessageService.java 소스 코드 >
package guest.service;
import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;
import java.util.List;
public class ListMessageService {
//-------------------------------------------------------------------
private int totalRecCount; // 전체 레코드 수
private int pageTotalCount; // 전체 페이지 수
private int countPerPage = 3; // 한페이지당 레코드 수
private static ListMessageService instance;
public static ListMessageService getInstance() throws MessageException
{
if( instance == null )
{
instance = new ListMessageService();
}
return instance;
}
private ListMessageService()
{
}
// 전체 메세지(레코드)의 갯수를 얻어오기
public int getTotalPage() throws MessageException {
totalRecCount = MessageDao.getInstance().getTotalCount();
int temp = (totalRecCount % countPerPage);
if (temp == 0) {
pageTotalCount = (totalRecCount/countPerPage);
} else {
pageTotalCount = (totalRecCount/countPerPage) + 1;
}
return pageTotalCount;
// pageTotalCount= (int)Math.ceil(totalRecCount/countPerPage);
}
public List <Message> getMessageList(int pageNo) throws MessageException
{
/*
페이지번호 시작레코드번호 끝레코드번호
1 1 3
2 4 6
3 7 9
4 10 12
*/
int firstRow = pageNo * countPerPage - 2;
int endRow = pageNo * countPerPage;
// 전체 레코드를 검색해 온다면
List <Message> mList = MessageDao.getInstance().selectList(firstRow, endRow);
return mList;
}
}
< DeleteMessageService.java 소스 코드 >
package guest.service;
import guest.model.Message;
import guest.model.MessageDao;
import guest.model.MessageException;
public class DeleteMessageService {
private static DeleteMessageService instance;
public static DeleteMessageService getInstance() throws MessageException
{
if( instance == null )
{
instance = new DeleteMessageService();
}
return instance;
}
private DeleteMessageService()
{
}
public int delete( String messageId, String password ) throws MessageException
{
int mId = 0;
if( messageId != null) mId = Integer.parseInt(messageId);
MessageDao mDao = MessageDao.getInstance();
return mDao.delete(mId, password);
}
}
< insertMessage.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 : {
guestName : { required : true, maxlength : 10 },
paasword : { required : true, maxlength : 10 },
message : { required : true, maxlength : 1024 }
}
});
// 버튼 클릭했을 때 데이터 넘어감
$('#frm').submit();
});
})
</script>
</head>
<body>
<form action="saveMessage.jsp" name="frm" id="frm" method="post">
이름 : <input type="text" name="guestName" id="guestName" required /><br/><br/>
암호 : <input type="password" name="password" id="password" required /><br/><br/>
메세지 : <textarea name="message" id="message" rows="3" cols="30" required></textarea><br/><br/>
<input type="button" id="btn" value="메세지 남기기">
</form>
</body>
</html>
< saveMessage.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="guest.service.WriteMessageService"%>
<% request.setCharacterEncoding("utf-8"); %>
<!--
0. 넘겨받는 데이타의 한글처리
1. 화면의 입력값을 Message 클래스로 전달
2. Service 클래스의 함수 호출
-->
<jsp:useBean id="m" class="guest.model.Message">
<jsp:setProperty name="m" property="*" />
</jsp:useBean>
<%
WriteMessageService.getInstance().write(m);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 남김 </title>
</head>
<body>
<font size="3" color="#bb44cc">
방명록에 메세지를 남겼습니다.
</font><br/><br/><br/>
<a href='listMessage.jsp'> [ 목록보기 ] </a>
</body>
</html>
< listMessage.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="guest.model.*,guest.service.*" %>
<%@ page import="java.util.List" %>
<%
String pNum = request.getParameter("page");
int pageNo = 1;
if (pNum != null) pageNo = Integer.parseInt(pNum);
// 전체 메세지 레코드 검색
// List <Message> mList = ListMessageService.getInstance().getMessageList();
ListMessageService service = ListMessageService.getInstance();
int totalPageCount = service.getTotalPage();
List <Message> mList = service.getMessageList(pageNo);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 목록 </title>
</head>
<body>
<% if( mList.isEmpty() ) { %>
남겨진 메세지가 하나도~~없습니다. <br>
<% } else { %>
<table border="1">
<% for(Message m : mList) { %>
<tr>
<td> <%= m.getId() %></td>
<td> <%= m.getGuestName() %></td>
<td><a href="deleteMessage.jsp?id=<%= m.getId() %>"> [삭제] </a></td>
</tr>
<tr>
<td colspan='3'>
<textarea cols=35 rows=3 style="font-family: '돋움', '돋움체'; font-size: 10pt; font-style: normal; line-height: normal; color: #003399;background-color:#D4EBFF;border:1 solid #00009C;"><%= m.getMessage() %></textarea>
</td>
</tr>
<% } // end of for %>
</table>
<% } // end if-else %>
<a href='insertMessage.jsp'>글쓰기</a>
<% for (int i=1; i<=totalPageCount; i++) { %>
<a href='listMessage.jsp?page=<%= i %>'>[ <%= i %>]</a>
<% } // end of for %>
</body>
</html>
< deleteMessage.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% String id = request.getParameter("id"); %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 방명록 삭제 </title>
</head>
<body>
메세지를 삭제하려면 암호를 입력하세요. <br/><br/>
<form action="deleteConfirm.jsp" method="post">
<input type='hidden' name='id' value='<%= id %>' />
암호 : <input type="password" name="password" />
<input type="submit" value="메세지 삭제"/>
</form>
</body>
</html>
< deleteConfirm.jsp 소스 코드 >
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="guest.service.DeleteMessageService" %>
<%
int delCnt = 0;
// 1. 앞의 화면에서 삭제할 번호와 패스워드를 넘겨받는다.
String id = request.getParameter("id");
String password = request.getParameter("password");
// 2. 서비스의 delete() 메소드로 1번의 값을 넘겨주고 삭제된 행 수를 리턴받아 delCnt 변수에 지정
delCnt = DeleteMessageService.getInstance().delete(id, password);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title> 메세지 삭제 확인 </title>
</head>
<body>
<% if( delCnt == 0 ) { %>
삭제할 메세지가 존재하지 않거나 비밀번호가 올바르지 않습니다.
<% } else { %>
메세지를 삭제하였습니다.
<% } %>
<br/><br/>
<a href="listMessage.jsp"> [ 목록보기 ] </a>
</body>
</html>