728x90

 

JDBC로 DB를 연결해서 DB연동 하고 있는 상태이고

반복적으로 사용되는 기능인 close와 transanction 같은 것들을 따로 Template클래스로 빼두어

import만하면 쉽게 사용할수 있게 코드가 구성되었고

db의 트랜잭션(commit & rollback)과

jdbc의 클래스 Connection, Statement, ResultSet의 close 기능 메소드를 만들었고

PreparedStatement는 Statement의 자식 클래스이기 때문에 다형성으로 인해 부모타입은 자식 객체를 다 받을 수 있으므로 해줄 필요 x

 

package common;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCTemplate {


	// commit()
	public static void commit(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.commit();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// rollback()
	public static void rollback(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.rollback();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// Connection의 close처리
	public static void close(Connection conn) {
		try {
			if(conn != null && !conn.isClosed()) { // conn.isClosed()은 SQLException 필요함
				conn.close();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// ResultSet의 close처리
//	public static void close(ResultSet rset) { 
//		// close(ResultSet rset)만 적었는데 위의 close와 다르게 에러 안나는 이유
//		// 답 : 오버로딩이 적용되었기 때문
//	}
	public static void close(ResultSet rset) { 
		try {
			if(rset != null && !rset.isClosed()) { // conn.isClosed()은 SQLException 필요함
				rset.close();
			}	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	// Statement의 close처리
	public static void close(Statement stmt) { 
		try {
			if(stmt != null && !stmt.isClosed()) {
				stmt.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	
}

 

728x90
반응형
728x90

 

 Statement & PreparedStatement차이 

1) Statement

완성된 쿼리라 손 볼 필요 x 따라서 보낼 때 한번에 쿼리만 전달하면 됨
                 ex)conn.createStatement();


 2)PreparedStatement

미완성 쿼리 . 비워져있는 부분을 채울 것임. 공간을 확보에 해놓은 것. 미완성 쿼리보내면 에러나기에 채워줘야함. 위치홀더 때문에 미완성된 쿼리라 비어있는 값을 채우기 위해 String query를 집어 넣고서 만든다
                 ex)conn.prepareStatement(query);

쿼리에  동적인 값이 많다면,  PreparedStatement가 유리. 코드가 짧아짐

 

 

model.DAO

// 메뉴2.사번으로 사원 정보 조회
	public int insertEmployee(Employee e) {		// return타입 변경 : void to int
		Connection conn = null;
		PreparedStatement pstmt = null;
		int result = 0;
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","SCOTT","qrwe");
//			conn.setAutoCommit(false); 		// 18c버젼에 추가해야하는 코드
			// 1) Statement 방식 쿼리문
			String query = "INSERT INTO EMP VALUES(" + e.getEmpNo() + ", "	// 완성된 쿼리이기에 -> Statement
													+ e.getEmpName() + ", "
													+ e.getJob() + ", "
													+ e.getMgr() + ", "
													+ "SYSDATE, "		    // 오늘 날짜 삽입
													+ e.getSal() + ", "
													+ e.getComnn() + ", "
													+ e.getDeptNo() + ") "; // 간단한 쿼리인데 자바로 옮겨쓰니 복잡해지고 길어짐.
			// Statement & PreparedStatement  둘 다 사용가능
			// 위의 쿼리처럼  동적인 값이 많다면,  PreparedStatement가 유리. 아래처럼 코드가 확 짧아짐
			
			// 2) PreparedStatement 방식 쿼리문
			String query2 = "INSERT INTO EMP VALUES(?, ?, ?, ?, SYSDATE, ? ,? ,?)"; // 
			pstmt = conn.prepareStatement(query2);
			pstmt.setInt(1, e.getEmpNo());
			pstmt.setString(2, e.getEmpName());
			pstmt.setString(3, e.getJob());
			pstmt.setInt(4, e.getMgr());
			pstmt.setInt(5, e.getSal());
			pstmt.setInt(6, e.getComnn());
			pstmt.setInt(7, e.getDeptNo());
			
			result = pstmt.executeUpdate(); // DML(insert,update,delete)문이라 executeUpdate():int 사용
			// 위의 conn.prepareStatement(query2); 이미 쿼리문을 보냈기 때문에 executeUpdate()안에 인자 필요x
			
			// 트랜젝션 처리
			// commit할지 rollback할지
			if(result > 0) {
				conn.commit();
			}else {
				conn.rollback();
			}
			
			
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (SQLException e1) {
			e1.printStackTrace();
		} finally {
			try {
				pstmt.close();
				conn.close();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}

		}
		
		return result;	// insertEmployee()의 반환타입 void to int로 변경
		
		// dml 삽입완료. 데이터 확정지을지 취소할지(커밋할지 말지) 정해야함.  
		
	}

 

728x90
반응형

+ Recent posts