ㅁ static import
import com.br.common.JDBCTemplate; 이 아닌
import static com.br.common.JDBCTemplate.*; 하면
Connection conn = JDBCTemplate.getConnection();
JDBCTemplate.close(conn);
이 아닌
Connection conn = getConnection();
close(conn);
이 가능하다.
ㅁ 모듈화 작업
- 지금까지 매번 똑같은 구문을 작성하고 있는데 한번만 정의하고 재사용하는 것을 모듈화라고 한다.
- Service 클래스의 구문을 모듈화해서 재사용한다.
- JDBCTemplate으로 공통코드 최소화.
ㅁ Service는 Dao의 역할을 분담한다.
(1) jdbc driver 등록
(2) Connection 객체 생성
(3) Statement 객체 생성
(4), (5) select문을 전달하면서 실행 후 결과(ResultSet) 받기
or insert, update, delete문을 전달하면서 실행 후 결과(int형) 받기
(6) 트랜잭션 처리 or ResultSet에 담겨있는 데이터값(컬럼값)들을 뽑아서 vo 객체의 각 필드에 옮겨담기
(7) 자원 반납( Connection ) ( ResultSet과 Statement )
(8) 결과 리턴
- 파란색은 Service, 빨간색은 Dao
- Dao는 sql문 실행만 집중한다.
ㅁ 모듈화 (Service에서 JDBCTemplate에 모듈화 한 메소드들을 사용한다)
- Connection 객체 생성 후 리턴하는 메소드 (jdbc driver 등록, Connection 객체 생성)
- commit 메소드 if( conn != null && !conn.isClosed() )
- rollback 메소드 if( conn != null && !conn.isClosed() )
- Connection 객체를 반납(close) 처리하는 메소드 if( conn != null && !conn.isClosed() )
- ResultSet 객체를 반납(close) 처리하는 메소드 if( rset != null && !rset.isClosed() )
- PreparedSet 객체를 반납(close) 처리하는 메소드 if( stmt != null && !stmt.isClosed() )
ㅁ 예시
- 이제 Service에서 메소드마다 Dao 가기 전에 Connection 객체를 생성하는 구문을 매번 진행한다.
그런데 메소드가 많아지면 그때마다 매번 이 긴 구문을 반복적으로 작성해야 한다.
그래서 매번 반복적으로 사용되는 구문을 한번만 정의하고 재사용하기 위해 모듈화한다.
- 저 구문을 별도의 메소드로 정의한다.
사실 이 클래스(Service 패키지) 내에서 메소드로 정의해도 되지만,
보통 모듈화 작업을 한다고 할 때는 클래스를 따로 정의함.
- JDBC 관련한 반복적인 구문을 따로 모아둔다.
com.br.common 패키지에 JDBCTemplate이라는 클래스를 새로 만들어서
메소드로 반복적으로 작성되는 구문을 정의한다.
ㅁ static 메소드로 선언한다.
- static 메소드로 선언하면 Service 측에서 JDBCTemplate 클래스의 메소드를 사용할 때 객체를 생성하지 않고 사용할 수 있다.
- Connection 객체 반납을 Dao가 아닌 Service에서 한다.
거기서 Connection 객체가 또 사용될 수 있어서 여기서 반납하면 안 된다.
ㅁ com.br.common.JDBCTemplate에 모듈화한 메소드들
- 이 메소드들을 쓰는건 Service 패키지의 클래스.
(1) Connection 객체 생성 후 리턴하는 메소드 (jdbc driver 등록, Connection 객체 생성)
public static Connection getConnection() {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:xe";
String username = "JDBC";
String password = "JDBC";
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
}
catch (ClassNotFoundException e) { e.printStackTrace(); }
catch (SQLException e) { e.printStackTrace(); }
return conn;
}
- 문자열들을 하드코딩된 채로 두지 않고 변수로 분리해두었다.
(2) commit 메소드 if( conn != null && !conn.isClosed() )
public static void commit(Connection conn) {
try {
if( conn != null && !conn.isClosed() ) {
conn.commit();
}
}
catch (SQLException e) { e.printStackTrace(); }
}
(3) rollback 메소드 if( conn != null && !conn.isClosed() )
public static void rollback(Connection conn) {
try {
if( conn != null && !conn.isClosed() ) {
conn.rollback();
}
}
catch (SQLException e) { e.printStackTrace(); }
}
(4) Connection 객체를 반납(close) 처리하는 메소드 if( conn != null && !conn.isClosed() )
public static void close(Connection conn) {
try {
if( conn != null && !conn.isClosed() ) { conn.close(); }
}
catch (SQLException e) { e.printStackTrace(); }
}
- close라는 같은 메소드 이름으로 여러 메소드 선언. (오버로딩)
(5) ResultSet 객체를 반납(close) 처리하는 메소드 if( rset != null && !rset.isClosed() )
public static void close(ResultSet rset) {
try {
if( rset != null && !rset.isClosed() ) { rset.close(); }
}
catch (SQLException e) { e.printStackTrace(); }
}
(6) PreparedSet 객체를 반납(close) 처리하는 메소드 if( stmt != null && !stmt.isClosed() )
public static void close(Statement stmt) { // 부모타입으로 선언해 두면 부모, 자식 객체 다 받을 수 있다.
try {
if( stmt != null && !stmt.isClosed() ) { stmt.close(); } // 변수명도 다 stmt로 선언해 둔다.
}
catch (SQLException e) { e.printStackTrace(); }
}
ㅁ 자원 반납하거나 트랜잭션 처리할 때 그냥 하면 안 되고 조건검사를 먼저 해야 한다.
- 닫으려는 객체가 null일 수 있다.
pstmt 만들다 예외가 발생한 경우, rset은 null이다.
그런데 finally에서 null인 rset.close()를 하면 NullPointerException이 발생한다.
- 트랜잭션도 트랜잭션을 처리할 때 사용하는 객체(conn 등)이 null인 경우
conn.commit()하면 NullPointerException이 발생한다.
'클라우드 활용 자바개발자 양성과정 > 02-2. JDBC' 카테고리의 다른 글
7. JDBC MVC패턴 실습문제 & 최종정리 (0) | 2024.08.01 |
---|---|
5. Properties (0) | 2024.08.01 |
3. PreparedStatement (0) | 2024.07.30 |
2. JDBC에 MVC 패턴 적용하기 (0) | 2024.07.29 |
1. JDBC 기본 (0) | 2024.07.29 |