본문 바로가기

기타

[JDBC] JDBC 실행 중 Statement와 PreparedStatement 차이


Statement란

-  Database에 SQL문을 전달하고 실행결과를 받아내는 객체
   (Statement: 부모클래스 / PreparedStatement: 자식클래스) 
-  Connection객체에 의해 프로그램에 리턴되는 객체와 그 메소드의 집합
- Connection클래스의 createStatement() 메소드 호출의 결과로 리턴됨 
- Statement 객체를 통해 SQL문을 executeQuery/executrUpdate 메소드의 인자로 전달, SQL 질의 수행

 

PreparedStatement(향상된 Statement클래스, Statement의 자손클래스)의 특징:

-  SQL문을 바로 실행하지 않고 잠시 보관하는 개념으로
   미완성된 SQL문을 DB로 먼저 전달하고, 실행 전 완성형태로 만들어 실행만 함  
- SQL문 작성시 추후 보완할 부분들을 ? (위치홀더)로 완성하여 둠 (미완성 sql문)
- 추후 PreparedStatement 클래스의 setString,setInt 메소드를 통하여 ?(위치 홀더)에 들어갈 값을 세팅
   =>   pstmt.setString(위치홀더 번째수, 넣을 String값);
      ---->  홑따옴표는 메소드가 자동으로 String양옆에 붙여줌. 생략
   => pstmt.setInt(위치홀더 번째수, 넣을 int값);
-  Connection클래스의 prepareStatement메소드 호출 시, 미완성된 SQL문을 인자값으로 전달하여
   PreparedStatement객체 생성. 
  각 위치 홀더에 맍는 값들은 세팅

 

Statement PreparedStatement 
완성된 SQL문
String sql = "    " 
미완성된 SQL문
String sql = "  ? , ? , ? "
(보완할 부분들은 위치홀더 ? 로 기입)
객체 생성시 createStatement 메소드 호출 (인자값 없음)
 stmt = conn.createStatement();
객체 생성시 prepareStatement 메소드 호출
(미완성 sql문 인자로 전달)
pstmt = conn.prepareStatement(sql); 

Statement객체를 통한 SQL문 실행 시 
execute 메소드의 인자값으로 sql문 전달

stmt.executeXXX(sql)

SQL문 실행 이전, 미완성된 문장을 
PreparedStatement클래스의 get메소드로 채워줌
   
pstmt.getString(?의 위치, 실제값)
pstmt.getInt(?의 위치, 실제값)

PreparedStatement객체를 통한 SQL문 실행 시 
execute 메소드의 인자값으로 sql문을 전달하지 않음
pstmt.executeXXX();

 

  

 

[VO]

  	private int userNo;
	private String userId;
	private String userPwd;
	private String userName;
	private String gender;
	private int age;
	private String email;
	private String phone;
	private String address;
	private String hobby;
	private Date enrollDate;

[Statement 클래스 사용한 JDBC연결]

public class MemberDao1 {
	public int insertMember(Member m) {
	  // * 변수선언
		Connection conn = null;
		Statement stmt = null;		
		int result = 0;
		// *완성된 sql문 작성
		String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL,"
				+ "'"+m.getUserId() + "',"
				+ "'"+m.getUserPwd() + "',"																
				+ "'"+m.getUserName() + "',"																
				+ "'"+m.getGender() + "',"																
					 +m.getAge() + ","																
				+ "'"+m.getEmail() + "',"																
				+ "'"+m.getPhone() + "',"																
				+ "'"+m.getAddress() + "',"																
				+ "'"+m.getHobby() + "', SYSDATE)";
	// * 드라이버 등록 + ClassNotFoundException 예외처리
	// 패키지에 library로 등록한 ojdbc6.jar 내의 oracle.jdbc.driver 패키지에 있는 OracleDriver클래스를 통해 드라이버 등록(DriverManager객체생성)
	// OracleDriver 클래스가 없을 수 있으니 예외처리 필수 (OracleDriver는 클래스이다!)
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		
		
	// * Connection 객체생성 (DriverManager객체를 통해 생성)+ SQLException예외처리
		conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
	// Statement 객체생성(Connection객체를 통해 생성)		
		stmt = conn.createStatement();
	// 	Statement객체를 통한 질의 수행 및 결과반환
	    result = stmt.executeUpdate(sql);
        
     // DML구문일 경우 트랜젝션
        if(result > 0 ) {
        	conn.commit();
         } else {
          	conn.rollback();
         }
		
		
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
	// 자원반납		
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
            
		}
        return result;
      }

[PreparedStatement 객체를 이용한 JDBC연결]

	public void insertMemberWithPstmt(Member m){
		// 변수선언
		int result = 0;
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		// 미완성된 SQL문 작성, 변수에 들어갈 자리에 위치홀더 (?)를 넣어둠!
		String sql = "INSERT INTO MEMBER VALUES(SEQ_USERNO.NEXTVAL,?,?,?,?,?,?,?,?,?,SYSDATE)";
		
		try {
		// Driver등록	
			Class.forName("oracle.jdbc.driver.OracleDriver");
		// Connection 객체 생성	
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
		// Connection객체의 prepareStatement 메소드에 "미완성된 sql문"을 인자로 전달,
		// PreparedStatement객체를 반환받음
			pstmt = conn.prepareStatement(sql);			
		// PreparedStatement객체의 위치홀더의 미완성 값들을 넣어줌 (PreparedStatement 객체의 setString,setInt 메소드)	
			pstmt.setString(1,m.getUserId());
			pstmt.setString(2, m.getUserPwd());		
			pstmt.setString(3, m.getUserName());
			pstmt.setString(4, m.getGender());																
			pstmt.setInt(5, m.getAge());																
			pstmt.setString(6, m.getEmail());
			pstmt.setString(7, m.getPhone());
			pstmt.setString(9, m.getAddress());
			pstmt.setString(8, m.getHobby());
	  // PreparedStatement객체의 executeXXX메소드를 통해 sql문 실행 및 결과값 반환받기 (sql문은 이미 전달했으므로 다시 전달하지 않음)
			result = pstmt.executeUpdate();
			if(result > 0 ) {
        		conn.commit();
         	} else {
          		conn.rollback();
       		}
		
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				pstmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} 
        return result;
	}