1. VO(Value Object) : 값 저장용 객체(저장된 값을 읽는 용도로 사용)
1-1 DTO(Data Transfer Object) : 데이터를 교환하는 용도의 객체
(값을 읽고 쓰고 하는 용도) // vo와 비슷한거
2. Service : 실제 프로그램이 제공하는 기능을 모아놓은 클래스
3. DAO (Data Access Object) : 데이터가 저장된 DB에 접근하는 객체
SQL 수행, 결과 반환 받는 기능을 수행
4. JDBCTemplate : JDBC에서 반복 사용되는 코드를 모아둔 클래스
모든 필드, 메서드가 static
5. Run : 코드 실행용 클래스
public class TestVO {
private int testNo;
private String testTitle;
private String testContent;
// 기본생성자
public TestVO() {} // ctrl + space 누르면 자동완성
// 매개변수 생성자 (모든 필드 초기화)
public TestVO(int testNo, String testTitle, String testContent) {
super();
this.testNo = testNo;
this.testTitle = testTitle;
this.testContent = testContent;
}
// getter/setter
public int getTestNo() {
return testNo;
}
public void setTestNo(int testNo) {
this.testNo = testNo;
}
public String getTestTitle() {
return testTitle;
}
public void setTestTitle(String testTitle) {
this.testTitle = testTitle;
}
public String getTestContent() {
return testContent;
}
public void setTestContent(String testContent) {
this.testContent = testContent;
}
// toString() 오버라이딩
@Override
public String toString() {
return "TestVO [testNo=" + testNo + ", testTitle=" + testTitle + ",
testContent=" + testContent + "]";
}
}
비즈니스로직(데이터 가공, 트랜잭션 제어)처리
하나의 Service메서드에서 n개의 DAO메서드 (지정된 SQL 수행)을 호출하여
이를 하나의 트랜잭션 단위로 취급.
한번에 COMMIT, ROLLBACK을 수행할 수 있다.
여러 DML을 수행하지 않는 경우라도 (단일 DML, SELECT등)
코드의 통일성을 지키기 위해서 Service에 작성
→ connection 객체 생성
public class TestService {
private TestDAO dao = new TestDAO();
/** 1행 삽입 서비스
* @param vo1
* @return result
*/
public int insert(TestVO vo1) throws SQLException {
// 1. 커넥션 생성 및 얻어오기
Connection conn = getConnection(); // import static .*;
//Connection conn = JDBCTemplate.getConnection();
//클래스명.메서드명(JDBCTemplate)에서 만든것
// 2. DAO 메서드를 호출하여 수행 후 결과 반환 받기
// -> Service에서 생성한 Connection 객체를 반드시 같이 전달해야한다!!!!
int result = dao.insert(conn, vo1); //
//result == SQL 수행 후 반영될 결과 행의 개수
// 3. 트랜잭션 제어
if(result > 0) commit(conn);
else rollback(conn);
// 4. 리턴전에 커넥션 반환(close)
close(conn);
// 5. 결과 반환
return result;
}
→ SQL 수행, 결과 반환 받는 기능을 수행
예시 : jdbc.model.dao패키지의 TestDAO 클래스를 만들경우
public class TestDAO {
// JDBC 객체를 참조하기 위한 참조변수 선언
private Statement stmt = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
private PreparedStatement pstmt;
// XML로 SQL을 다룰 예정 -> Properties 객체 사용
private Properties prop = null;
// 기본 생성자
public TestDAO() {
//dao가 기본생성자일 때
// 1. try-catch문 작성해서 properties 객체 생성하기
try {
prop = new Properties(); // Properties 객체 생성
prop.loadFromXML(new FileInputStream("test-query.xml"));
// test-query.xml 파일의 내용을 읽어와 Properties 객체에 저장
} catch (Exception e) {
e.printStackTrace();
}
}
/** 1행 삽입 DAO
* @param conn
* @param vo1
* @return result
*/
public int insert(Connection conn, TestVO vo1) throws SQLException {
// throws SQLException
// -> 호출한 곳으로 발생한 SQLException을 던짐
// -> 예외 처리를 모아서 진행하기 위해서
// 1. 결과 저장용 변수 선언
int result = 0;
try {
// 2. 커넥션 생성
Class.forName(driver);
conn = DriverManager.getConnection(url, user, pw);
// AutoCommit 비활성화
conn.setAutoCommit(false);
// 3. SQL 작성(test-query.xml에 작성된 SQL 얻어오기) --> prop이 저장하고 있음!
String sql = prop.getProperty("insert");
// String sql = "INSERT INTO TB_TEST VALUES(?, ?, ?)"
// 4. PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// -> throws Exception 쓰면 빨간줄 사라짐
// 5. ? (위치홀더)에 알맞은 값 세팅
// 물음표 순서대로 숫자 붙여주기
pstmt.setInt(1, vo1.getTestNo()); // 1
pstmt.setString(2, vo1.getTestTitle()); // 제목1
pstmt.setString(3, vo1.getTestContent()); // 내용1
// 6. SQL 수행 결과 (ResultSet) 반환 받기
result = pstmt.executeUpdate();
// executeQuery() : SELECT 수행 후 Result 반환
// excuteUpdate() : DML(INSERT, UPDATE, DELETE) 수행 후 결과 행 개수(int) 반환
// 7. 트랜잭션 제어 처리
// -> DML 성공 여부에 따라서 commit, rollback 제어
if (result > 0 ) conn.commit(); // DML 성공시 commit
else conn.rollback(); //DML 실패시 rOLLbACK
} finally {
//8. 사용한 JDBC 객체 자원 반환 ( close() )
try { if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
} catch (Exception e) {
e.printStackTrace();
}
// 9.
return result;
}
예시 : jdbc.common패키지의 JDBCTemplate 클래스를 만들경우
public class JDBCTemplate {
private static Connection conn = null;
// static메서드에서 필드를 사용하기 위해서는 필드도 static필드여야만 한다!
/** DB 연결 정보를 담고있는 Connection 객체 생성 및 반환 메서드
* @return conn
*/
public static Connection getConnection() {
try {
// 현재 커넥션 객체가 없을 경우 -> 새 커넥션 객체를 생성
if(conn == null || conn.isClosed()) {
// conn.isClosed() : 커넥션이 close 상태이면 true 반환
Properties prop = new Properties();
//Map<String, String> 형태의 객체, XML 입출력 특화
//driver.xml 파일 읽어오기
prop.loadFromXML( new FileInputStream("driver.xml") );
// -> XML 파일에 작성된 내용이 Properties 객체 모두 저장됨.
//XML에서 읽어온 값을 모두 String 변수에 저장
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
// 커넥션 생성
Class.forName(driver); // Oracle JDBC Driver 객체 메모리에 로드
// DriverManager를 이용해 Connection 객체 생성
conn = DriverManager.getConnection(url, user, password);
// 개발자가 직접 트랜잭션을 제어할 수 있도록 자동 커밋 비활성화
// Connection 객체 생성시
// AutoCommit이 활성화 되어 있는 상태이기 때문에
// // 이를 해제하는 코드를 추가!
conn.setAutoCommit(false);
}
} catch(Exception e) {
System.out.println("[Connection 생성 중 예외 발생]");
e.printStackTrace();
}
return conn;
}
/** Connection 객체 자원 반환 메서드
* @param conn
*/
public static void close(Connection conn) {
try {
// 전달받은 conn이
// 참조하는 connection 객체가 있고,
// 그 Connection 객체가 close 상태가 아니라면
if (conn != null && !conn.isClosed()) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/** Statement(부모), PreparedStatement(자식) 객체 자원 반환 메서드
* (다형성, 동적바인딩-런타임때일어남) 정적바인딩-컴파일때일어남
* @param stmt
*/
public static void close(Statement stmt) {
// 오버로딩 과적하는거 , 오버라이딩은 재정의 하는거
try {
if( stmt != null && !stmt.isClosed() ) stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/** ResultSet 객체 자원 반환 메서드
* @param rs
*/
public static void close(ResultSet rs) {
try {
if( rs != null && !rs.isClosed() ) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/** 트랜잭션 Commit 메서드
* @param conn
*/
public static void commit(Connection conn) {
try {
// 연결되어 있는 Connection 객체일 경우에만 Commit 진행
if(conn != null && !conn.isClosed() ) conn.commit();
} catch(SQLException e) {
e.printStackTrace();
}
}
/** 트랜잭션 Rollback 메서드
* @param conn
*/
public static void rollback(Connection conn) {
try {
// 연결되어 있는 Connection 객체일 경우에만 rollback 진행
if(conn != null && !conn.isClosed()) conn.rollback();
} catch(SQLException e) {
e.printStackTrace();
}
}
}