guestbook.model 패키지에서 DB에 접근 용이하게 하도록 변수마다 get/set 함수들을 만들어준다. 이때 변수의 타입은 외부에서 변경 불가 하도록 private.
(1)guestbook.model/Message.java
package guestbook.model;
public class Message {
private int id;
private String guestName;
private String password;
private String 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;
}
public boolean hasPassword() {
return password != null && !password.isEmpty();
}
public boolean matchPassword(String pwd) {
return password != null && password.equals(pwd);
}
}
(2) guestbook.model/MessageListView.java
package guestbook.model;
import java.util.List;
public class MessageListView {
private int messageTotalCount;
private int currentPageNumber;
private List<Message> messageList;
private int pageTotalCount;
private int messageCountPerPage;
private int firstRow;
private int endRow;
public MessageListView(List<Message> messageList, int messageTotalCount, int currentPageNumber,
int messageCountPerPage, int firstRow, int endRow) {
this.messageList = messageList;
this.messageTotalCount = messageTotalCount;
this.currentPageNumber = currentPageNumber;
this.messageCountPerPage = messageCountPerPage;
this.firstRow = firstRow;
this.endRow = endRow;
calculatePageTotalCount();
}
// 페이지 수 확장 메서드 private calculatePageTotalCount()
// 외부에서 변경 불가하게 설정.
private void calculatePageTotalCount() {
if (messageTotalCount == 0) { //전체 메세지의 수가 0이면, 페이지의 수도 0이다.
pageTotalCount = 0;
} else {
pageTotalCount = messageTotalCount / messageCountPerPage;
if (messageTotalCount % messageCountPerPage > 0) {
pageTotalCount++;
}
}
}
public int getMessageTotalCount() {
return messageTotalCount;
}
public int getCurrentPageNumber() {
return currentPageNumber;
}
public List<Message> getMessageList() {
return messageList;
}
public int getPageTotalCount() {
return pageTotalCount;
}
public int getMessageCountPerPage() {
return messageCountPerPage;
}
public int getFirstRow() {
return firstRow;
}
public int getEndRow() {
return endRow;
}
public boolean isEmpty() {
return messageTotalCount == 0;
}
}
서비스 클래스를 구현할 때, 효율성을 높이도록 MessageDao에서 많이 사용하는 부분들을
메서드로 정의해준다. 예를 들면, DB에 데이터를 삽입(select)/수정(update)/출력(select) /삭제(delete)하는 메서드나 Connection 메서드 등을 구현한다.
(3)guestbook.dao/MessageDao.java
package guestbook.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import guestbook.model.Message;
import jdbc.JdbcUtil;
public class MessageDao {
//<싱글톤 처리>
// DAO 클래스는 기능 클래스 --> 여러 개의 인스턴스 생성이 불필요하다.
// 결론 --> 싱글톤 패턴으로 처리 하자.
// 1.private 생성자
private MessageDao() {
}
// 2.인스턴스 생성 : 1개 생성하고 공유해서 사용.
private static MessageDao instance = new MessageDao();
// 3. 외부에서 사용할 수 있는 메서드 생성.
public static MessageDao getInstance() {
return instance;
}
//insert() 메서드
public int* insert(Connection conn, Message message) throws SQLException {
PreparedStatement pstmt = null;
String sql ="insert into guestbook_message values (message_id_seq.NEXTVAL, ?, ?, ?)";
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, message.getGuestName());
pstmt.setString(2, message.getPassword());
pstmt.setString(3, message.getMessage());
return pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtil.close(pstmt);
}
return 0;
}
//selectCount() 메세지_for 리스트 전체 게시물 수_messageTotalCount.
public int* selectCount(Connection conn) throws SQLException {
Statement stmt = null;
ResultSet rs = null;
String sql = "select count(*) from guestbook_message";
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
rs.next();
return rs.getInt(1);
}finally {
JdbcUtil.close(rs);
JdbcUtil.close(stmt);
}
}
// selectList()
public List<Message> selectList(Connection conn, int firstRow, int endRow)
throws SQLException {
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Message> messageList = null;
String sql = "select message_id, guest_name, password, message " +
"from ( " +
"select rownum rnum, message_id, guest_name, password, message " +
"from ( " +
"select * " +
"from guestbook_message m " +
"order by m.message_id desc " +
") " +
"where rownum <= ? " +
") " +
"where rnum >= ? " +
"";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, endRow*);
pstmt.setInt(2, firstRow*);
rs = pstmt.executeQuery();
if(rs.next()) {
messageList = new ArrayList<Message>();
do {
messageList.add(makeMessageFromResultSet(rs));*
//ResultSet rs의 결과가 있다면 읽어와서 messageList에 삽입해준다.
}while(rs.next());
}else {
messageList = Collections.emptyList();
}
return messageList;
}
//ResultSet rs의 결과가 있다면 읽어오는 메서드.
private Message makeMessageFromResultSet(ResultSet rs) throws SQLException {
Message message = new Message();
message.setId(rs.getInt("message_id"));
message.setGuestName(rs.getString("guest_name"));
message.setPassword(rs.getString("password"));
message.setMessage(rs.getString("message"));
return message;
}
}
* insert(Connection conn, Message message)/selectCount(Connection conn)
메서드 타입은 int라는 것을 주의해야한다. 왜 int로 했는가? 하면, 메서드가 실행이 되었는지 안되었는지 추후에 확인하기 위하여 int로 했다고 할 수 있다.
(4) GetMessageListService.java
이 메서드가 해당 페이지 인덱스(index)를 클릭하면 알맞은 리스트를 가져오는 핵심 클래스라 할 수 있다.
selectCount()와 selectList() 메서드를 MessageDao.java 클래스에서 가져온다.
package guestbook.service;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import guestbook.dao.MessageDao;
import guestbook.model.Message;
import guestbook.model.MessageListView;
import jdbc.connection.ConnectionProvider;
public class GetMessageListService {
//싱글톤
private static GetMessageListService instance = new GetMessageListService();
public static GetMessageListService getInstance() {
return instance;
}
private GetMessageListService() {
}
// 한 페이지에 보여줄 메시지의 수
private static final int MESSAGE_COUNT_PER_PAGE = 3;
//Message 리스트를 가져올 메서드 getMessageList(int pageNumber)
//페이지 넘버를 입력하면 리스트를 가져와야 한다.
public MessageListView getMessageList(int pageNumber) throws ServiceException {
Connection conn = null;
MessageDao dao = null;
int currentPageNumber = 1; //currentPageNumber의 default 값은 1
//현재 페이지 넘버 구하기
if(pageNumber > 0) {
currentPageNumber = pageNumber;
}
try {
conn = ConnectionProvider.getConnection(); //DB연결 작업
dao = MessageDao.getInstance(); //메서드 작업
// 전체 게시물의 수
int messageTotalCount = dao.selectCount(conn);
//게시물의 리스트
List<Message> messageList = null;
int firstRow = 0;
int endRow = 0;
//firstRow 와 endRow 구해서, 그 안의 리스트 뽑기
if(messageTotalCount > 0) {
firstRow = (currentPageNumber - 1)*MESSAGE_COUNT_PER_PAGE;
endRow = firstRow+ MESSAGE_COUNT_PER_PAGE - 1 ;
messageList = dao.selectList(conn,firstRow, endRow);
}else {
currentPageNumber = 0;
messageList = Collections.emptyList();
}
return new MessageListView(
messageList,
messageTotalCount,
currentPageNumber,
MESSAGE_COUNT_PER_PAGE,
firstRow,
endRow);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
(5) list.jsp
요청을 받는 뷰(JSP)이다.
<%@page import="guestbook.model.Message"%>
<%@page import="guestbook.model.MessageListView"%>
<%@page import="guestbook.service.GetMessageListService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String pageNumberStr = request.getParameter("page");
int pageNumber = 1;
if (pageNumberStr != null) {
pageNumber = Integer.parseInt(pageNumberStr);
}
GetMessageListService messageListService = GetMessageListService.getInstance();
MessageListView viewData = messageListService.getMessageList(pageNumber);
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>GuestBook</title>
<style>
</style>
</head>
<body>
<form action="writeMessage.jsp" method="post">
이름: <input type="text" name="guestName" /> <br /> 암호: <input
type="password" name="password" /> <br /> 메시지:
<textarea name="message" cols="30" row="3"></textarea>
<br /> <input type="submit" value="메시지 남기기" />
</form>
<hr>
<%
if (viewData.isEmpty()) {
%>
<h1>등록된 메시지가 없습니다.</h1>
<%
} else {
%>
<table border="1">
<%
for (Message message : viewData.getMessageList()) {
%>
<tr>
<td>메시지 번호: <%=message.getId()%><br />
손님 이름: <%=message.getGuestName()%><br />
메시지: <%=message.getMessage()%> <br />
<a href="confirmDeletion.jsp?messageId=<%=message.getId()%>">[삭제하기]</a>
</td>
</tr>
<%}%>
</table>
전체 페이지 카운트 <%= viewData.getPageTotalCount()%> <br>
<%for (int i = 1 ; i <= viewData.getPageTotalCount() ; i++) {%>
<a href="list.jsp?page=<%= i %>">[<%= i %>]</a>
<% }
}%>
</body>
</html>
댓글 없음:
댓글 쓰기