이번 포스팅은 mysql, 오라클, mssql에서 동작하는 방명록 예제를 작성할 것이다. 이를 통해 mvc패턴이 어떻게 적용되는지 볼 것이다.
1. 클래스 구조
서비스 관련 클래스
GetMessageListService - 요청한 페이지 번호에 포함된 메시지 목록을 구한다.
WriteMessageService - 방명록에 메시지를 작성하는 기능을 제공한다.
DeleteMessageService - 작성한 메시지를 삭제하는 기능을 제공한다.
DAO 관련 클래스
MessageDaoProviderInit - 초기화 서블릿으로서 MessageDaoProvider에서 사용할 DBMS종류를 선택한다.
MessageDaoProvider - 설정에 맞는 DB에 공통으로 적용될 수 있는 MessgageDao객체를 중개자역할 처럼 제공해준다.
MessageDao - GUESTBOOK_MESSAGE테이블에 대한 (추후 생성할 메세지 관련 테이블) CRUD 기능을 정의한 추상 클래스이다. 추상 클래스로 정의한 이유는 모든 DBMS에 공통으로 적용 될 수 있는 부분을 정의하고 각 DB별로 상이한 코드는 이 클래스르르 상속받아서 작성하게끔 하기 위함이다.
cf> CRUD란? 대부분의 소프트웨어가 가지고 있는 기본적인 데이터 처리기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 하는 말이다.
MySQLMessageDao, OracleMessageDao, MSSQLMessageDao 각 디비에 맞는 쿼리를 수행하는 Dao클래스.
JDBC Connection 관련 클래스 (추후 설명)
ConnectionProvider - Connection을 제공한다.
DBCPInit - DBCP 초기화 서블릿
2. 테이블 구성
GUESTBOOK_MESSAGE 스키마
필드이름 |
필드타입 |
설명 |
MESSAGE_ID |
INT |
메세지 번호(PK) |
GUEST_NAME |
VARCHAR(50) |
손님 이름 |
PASSWORD |
VARCHAR(10) |
메세지 암호 |
MESSAGE |
LONG VARCHAR |
메세지 |
메세지값을 전달할 때 (DAO로) 사용되는 모델인 Message 클래스를 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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(); } } | cs |
참고로 위의 DB테이블의 칼럼과 매핑되는 프로퍼티 목록(변수 혹은 필드라고도 하는)을 가지고 있다. 쉽게 말해서 각 칼럼이름과 다 똑같이 만드는 것이다.
3. MessageDao 클래스의 구현
MessageDao 클래스는 GUESTBOOK_MESSAGE 테이블에 대한 CRUD 쿼리를 실행해 주는 메서드를 정의하고 있는 추상 클래스이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import mvjsp.chap13.model.Message; import mvjsp.jdbc.JdbcUtil; public abstract class MessageDao { public abstract int insert(Connection conn, Message message) throws SQLException; public Message select(Connection conn, int messageId) throws SQLException { PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = conn.prepareStatement( "select * from guestbook_message where message_id = ?"); pstmt.setInt(1, messageId); rs = pstmt.executeQuery(); if (rs.next()) { return makeMessageFromResultSet(rs); } else { return null; } } finally { JdbcUtil.close(rs); JdbcUtil.close(pstmt); } } protected 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; } public int selectCount(Connection conn) throws SQLException { Statement stmt = null; ResultSet rs = null; try { stmt = conn.createStatement(); rs = stmt.executeQuery("select count(*) from guestbook_message"); rs.next(); return rs.getInt(1); } finally { JdbcUtil.close(rs); JdbcUtil.close(stmt); } } public abstract List<Message> selectList(Connection conn, int firstRow, int endRow) throws SQLException; public int delete(Connection conn, int messageId) throws SQLException { PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = conn.prepareStatement( "delete from guestbook_message where message_id = ?"); pstmt.setInt(1, messageId); return pstmt.executeUpdate(); } finally { JdbcUtil.close(rs); JdbcUtil.close(pstmt); } } } | cs |
line 13 - insert는 각 DB별로 상이하기 때문에 상속받아서 작성한다.
line 35 - makeMessageFromResultSet 에서는 ResultSet에서 값을 가져와서 모델에 하나씩 넣는 과정이다.
cf> ResultSet
java document에서 발췌한 내용이다.
인터페이스이며 읽어온 db의 내용을 가져올수있는 커서 포인터를 갖고있다고 한다. next로 포인터를 옮겨가며 레코드를 참조하게 될 것이다. 메소드는 직관적이니 보면 이해할 수 있을 것이다. ex) getInt, getString ...
Interface ResultSet
- All Superinterfaces:
- AutoCloseable, Wrapper
- All Known Subinterfaces:
- CachedRowSet, FilteredRowSet, JdbcRowSet, JoinRowSet, RowSet, SyncResolver, WebRowSet
public interface ResultSet extends Wrapper, AutoCloseable
A table of data representing a database result set, which is usually generated by executing a statement that queries the database.A
ResultSet
object maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row. Thenext
method moves the cursor to the next row, and because it returnsfalse
when there are no more rows in theResultSet
object, it can be used in awhile
loop to iterate through the result set.
line 45 - selectCount는 테이블에서 저장된 행의 개수를 리턴한다.
line 59 - 시작행과 끝행에 해당되는 메세지목록을 읽어온다.
line 62 - 지정핞 주요키에 해당하는 행의 데이터를 삭제하는 쿼리를 실행하고 삭제된 행의 행의 갯수를 리턴한다.
다음 포스팅에선 Mysql에서 DAO를 작성해보자.
[소스출처] - 최범균의 JSP 웹프로그래밍
'프로그래밍 > MVC pattern' 카테고리의 다른 글
방명록 구현을 통한 MVC 패턴 이해하기 (2) (0) | 2017.01.16 |
---|---|
MVC 패턴에서 쓰이는 DAO, 서비스의 개념 및 구현방법 (0) | 2017.01.13 |