list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>방명록 메시지 목록</title>
</head>
<body>
<form method="post" action="writeMessage.jsp">
이름: <input type="text" name="guestName" /><br />
비밀번호:<input type="text" name="password" /><br />
내용:<textarea rows="3" cols="30" name="message"></textarea><br />
<input type="submit" value="메시지 남기기" />
</form>
</body>
</html>
writeMessage.jsp
<%@page import="guestbook.service.WriteMessageService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
%>
<!DOCTYPE html>
<html>
<head>
<title>방명록 메시지 남김</title>
</head>
<body>
<jsp:useBean id="guestbookMessage" class="dto.GuestbookMessage">
<jsp:setProperty name="guestbookMessage" property="*" />
</jsp:useBean>
${guestbookMessage.messageId}<br />
${guestbookMessage.guestName}<br />
${guestbookMessage.password}<br />
${guestbookMessage.message}<br />
<%-- <%=guestbookMessage.getGuestName()%> 위의 el태그와 같은 의미 --%>
<%
WriteMessageService writeMessageService =
WriteMessageService.getinstance();//서비스 객체 생성
writeMessageService.write(guestbookMessage);//write메서드 호출
%>
방명록에 메시지를 남겼습니다.<br />
<a href="list.jsp">[목록보기]</a>
</body>
</html>
GuestbookMessage.java
package dto;
//자바빈 클래스
public class GuestbookMessage {
private int messageId;
private String guestName;
private String password;
private String message;
public GuestbookMessage() {
super();
// TODO Auto-generated constructor stub
}
public int getMessageId() {
return messageId;
}
public void setMessageId(int messageId) {
this.messageId = messageId;
}
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 GuestbookMessage(int messageId, String guestName, String password, String message) {
super();
this.messageId = messageId;
this.guestName = guestName;
this.password = password;
this.message = message;
}
@Override
public String toString() {
return "GuestbookMessage [messageId=" + messageId + ", guestName=" + guestName + ", password=" + password
+ ", message=" + message + "]";
}
}
WriteMessageService.java
package guestbook.service;
import java.sql.Connection;
import java.sql.SQLException;
import dto.GuestbookMessage;
import guestbook.dao.MessageDao;
import jdbc.ConnectionProvider;
import jdbc.JdbcUtil;
//***Service.java => 비즈니스(기능) 로직
public class WriteMessageService {
private static WriteMessageService instance = new WriteMessageService();
public static WriteMessageService getinstance() {
return instance;
}
private WriteMessageService() {}
public void write(GuestbookMessage message) {
//커넥션 객체를 선언(DBCP에서 가져온 커넥션)
Connection conn = null;
try {
//BDCP 커넥션 객체를 생성
conn = ConnectionProvider.getConnection();
//guestbook_message테이블로 insert => Data Access Object 영역
MessageDao messageDao = MessageDao.getInstance();
int result = messageDao.insert(conn, message);
//성공하면 1 실패하면 0
}catch(SQLException ex) {
throw new ServiceException("메시지 등록 실패:"+ex.getMessage(),ex);
}finally {
JdbcUtil.close(conn);
}
}
//끝을 만나면 자동으로 return되지만 빈손임
}
MessageDao.java
package guestbook.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import dto.GuestbookMessage;
import jdbc.JdbcUtil;
//Data Access Object
public class MessageDao {
//싱글톤 패턴
private static MessageDao instance = new MessageDao();
public static MessageDao getInstance() {
return instance;
}
private MessageDao() {}
guestbook_message 테이블로 insert
insert, update, delete 기본 return type은 int
params : 커넥션 객체, 무엇을
public int insert(Connection conn, GuestbookMessage message) {
//db연결객체와 (con객체) 입력한 데이터가 들어있는 dto 객체가 온것
//선언
PreparedStatement pstmt = null;
int result=0;
try {
pstmt = conn.prepareStatement(
"insert into guestbook_message(message_id,.guest_name ,password,message,)" +
"values(" +
"(select nvl(max(message_id), 0)+1 from guestbook_message)" +
",?,?,?" +
")"
);
pstmt.setString(1, message.getGuestName());
pstmt.setString(2, message.getPassword());
pstmt.setString(3, message.getMessage());
return pstmt.executeUpdate();//dao로 돌아감
}catch(SQLException ex) {
ex.printStackTrace();
return 0;
}finally {
//주의!! 커넥션 객체는 비즈니스로직에서 닫음(service)
JdbcUtil.close(pstmt);
}
}
}
ConnectionProvider.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
//커넥션을 제공해주는 클래스
public class ConnectionProvider {
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(
"jdbc:apache:commons:dbcp:ddit");
}
}
ServiceException.java
package guestbook.service;
public class ServiceException extends RuntimeException {
//생성자
public ServiceException(String message, Exception cause) {
super(message, cause);//이놈들을 RuntimeException 여기로 날림
}
//생성자
public ServiceException(String message) {
super(message);
}
}
DBCPInit.java
package jdbc;
import java.sql.DriverManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
//서블릿 클래스
public class DBCPInit extends HttpServlet{
@Override
public void init() throws ServletException{//톰켓으로 던져서 웹브라우져에 찍을거임 , 톰켓에 오류가남
//JDBC Driver를 로딩
loadJDBCDriver();
//커넥션풀을 초기화
initConnetionPool();
}
//JDBC Driver를 로딩
private void loadJDBCDriver() {
try {
//커넥션풀이 내부에서 사용할 JDBC Driver를 로딩함
Class.forName("oracle.jdbc.driver.OracleDriver");//문제가 생기면 호출한 곳으로 던져짐
}catch(ClassNotFoundException ex) {
throw new RuntimeException("fail to load JDBC Driver", ex);//톰켓이 실행이 되고 실행됨
}
}
//커넥션풀을 초기화
private void initConnetionPool() {
try {
//의국에서 새로운 의사를 생성할 때 필요한 외과가 있어야 함
//커넥션풀에서 새로운 커넥션 을 생성할 때 사용할 커넥션 펙토리를 생성
ConnectionFactory connFactory = new DriverManagerConnectionFactory(
"jdbc:oracle:thin:@localhost:1521:xe",
"jspexam",
"java"
);
//DBCO는 커넥션풀에 커넥션을 보관할 때 PoolableConnection을 사용
//이 Class는 내부적으로 실제 Connection을 담고 있음
//커넥션 풀을 관리
PoolableConnectionFactory poolableConnFactory =
new PoolableConnectionFactory(connFactory, null);
//커넥션이 유효한지 여부 검사 시 사용할 쿼리
poolableConnFactory.setValidationQuery("select 1");
//커넥션 풀의 설정 정보 생성
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
//유효 커넥션 검사 주기(1/1000초)
//놀고 있는 커넥션을 풀에서 제거하는 시간 기준(5분)
poolConfig.setTimeBetweenEvictionRunsMillis(1000L * 60L * 5L);
//풀에 보관중인 커넥션이 유효한지 검사할지 여부
poolConfig.setTestWhileIdle(true);
//커넥션 최소 개수
poolConfig.setMinIdle(4);
//커넥션 최대 개수
poolConfig.setMaxIdle(50);
//커넥션풀의 설정 정보를 생성, 팩토리와 커넥션풀 설정을 파라미터로 받음
GenericObjectPool<PoolableConnection> connectionPool =
new GenericObjectPool<>(poolableConnFactory, poolConfig);
//풀러불커넥션팩토리에도 생성이된 커넥션 풀을 연결
poolableConnFactory.setPool(connectionPool);
//커넥션 풀을 제공하는 JDBC 드라이버를 등록함
//oracle.jdbc.driver.OracleDriver
Class.forName("org.apache.commons.dbcp2.PoolingDriver");
PoolingDriver driver =
(PoolingDriver)DriverManager.getDriver("jdbc:apache:commons:dbcp:");
//커넥션 풀 드라이버에 생성된 커넥션 풀을 등록
//jdbc:apache:commons:dbcp:ddit
driver.registerPool("ddit", connectionPool);
}catch(Exception e){
throw new RuntimeException(e);//
}//end try
}//end initConnectionPool()
}
jdbcUtil.java
package jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
//하나의 클래스에 같은 이름의 메소드를 여러번 사용 가능?
//오버로딩
public class JdbcUtil {
public static void close(ResultSet rs) {
if(rs!=null)try {rs.close();}catch(SQLException ex) {}
}
public static void close(Statement stmt) {
if(stmt!=null)try {stmt.close();}catch(SQLException ex) {}
}
public static void close(Connection conn) {
if(conn!=null)try {conn.close();}catch(SQLException ex) {}
}
public static void close(PreparedStatement pstmt) {
if(pstmt!=null)try {pstmt.close();}catch(SQLException ex) {}
}
public static void rollback(Connection conn) {
if(conn!=null)try {conn.rollback();}catch(SQLException ex) {}
}
}