jdbc - preparedStatement

56742 ワード

preparedStatement
package ex01.jdbcp.pstmt;

import java.sql.*;
/*
Statement 
 - 실행시 sql문을 받아서 오라클 서버에 전송하기 알맞은 형태로 변환해서 전송한다.
PreparedStatement
 - 객체 생성시 sql문을 받아서 미리 알맞은 형태로 변환하고 전송하기 직전에 
   ? 부분만 변수 값으로 받아서 전송한다.
 - sql 문의 구조는 동일하되 파라미터 값만 변경될 때 Statement 보다 속도가 빠르다. 
  왜냐하면 객체 생성시 미리 sql문의 구조를 최적화 해놨기 때문이다.
  그래서 파라미터만 변경되고 sql문의 구조는 미리 최적화 해놓은 그대로 상태를 재활용하므로 
  속도가빠를 수 밖에 없다. 
*/

public class PrepareStatementEx {
	// 1. 오라클 접속에 필요한 클래스를 메모리로 로딩한다
	static {
		try { // class not found exception 해결을 위해 try catch문으로 감싼다.
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

		// 2. url, id, pass
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String id = "bitTest";
		String pass = "bitTest";

		// 3. 클래스 변수 선언
		Connection con = null; // 오라클 접속에 필요
		PreparedStatement preStmt = null; // SQL문 실행에 필요
		ResultSet rs = null; // Select문 결과값 저장에 필요

		try {
			// 4. 오라클 접속
			con = DriverManager.getConnection(url, id, pass);

			// 5. 테이블 생성
			String strCreate = "CREATE TABLE student (\n" 
                    + "  sno varchar2(8) PRIMARY KEY, \n"
					+ "  sname varchar2(10),\n" 
                    + "  sex varchar2(3),\n" 
                    + "  syear number(1),\n"
					+ "  major varchar2(10),\n" + "  avr number(4,2)\n" + ")";

			preStmt = con.prepareStatement(strCreate);
			int cnt = preStmt.executeUpdate();
			System.out.println("결과값 : " + cnt);

			// 6. 데이터 삽입
			String strInsert = "INSERT INTO student (sno, sname, sex, syear, major, avr) 
                                 VALUES (?,?,?,?,?,?)";
			preStmt = con.prepareStatement(strInsert);
			// '915301','공융','남',4,'화학',0.95 물음표는 밑에 넣은 값들로 채워진다.
			preStmt.setString(1, "915301");
			preStmt.setString(2, "공융");
			preStmt.setString(3, "남");
			preStmt.setInt(4, 4);
			preStmt.setString(5, "화학");
			preStmt.setDouble(6, 0.95);

			cnt = preStmt.executeUpdate();
			System.out.println(cnt + "개 행 적용");

			// 7. 결과 검사
			String strSelect = "SELECT * FROM student";
			preStmt = con.prepareStatement(strSelect);
			rs = preStmt.executeQuery();
			int idx = 1;
			while (rs.next()) {       //rs는 next를 실행하는 순간 첫번째를 가리키게 된다.
				System.out.println("--------[ " + idx + " ]---------");
				System.out.println("sno : " + rs.getString(1));
				System.out.println("sname : " + rs.getString(2));
				System.out.println("sex : " + rs.getString(3));
				System.out.println("syear : " + rs.getInt(4));
				System.out.println("major : " + rs.getString(5));
				System.out.println("avr : " + rs.getDouble(6));
				idx++;
			}

		
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				// 8. 열린 객체 모두 닫기 , finally는 정상실행이든 예외가 발생하든 무조건 처리해준다.
				// null이 아니라는 것은 정상실행되었다는 것이므로 닫아라.
				if (rs != null) rs.close();
				if (preStmt != null) preStmt.close();
				if (con != null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
差異
文更新時にオブジェクトを挿入
Statement statemt = con.createStatement();  //Statement 객체 생성
String strInsert = "INSERT INTO emp (eno, ename) " + "\r\n" + 
					"VALUES ('9000', '홍길동')";
int cnt = statemt.executeUpdate(strInsert); // 이때 insert 객체를 넣음
しかし、準備された声明.
String strInsert = "INSERT INTO student (sno, sname, sex, syear, major, avr) VALUES (?,?,?,?,?,?)";
preStmt = con.prepareStatement(strInsert); //preStmt 객체를 생성하면서 객체를 넣음
このように、オブジェクト生成時にsql文を加えて最適化します.(構造最適化)
----->繰り返し作業で速度に差があります.
例:
"INSERT INTO student (sno, sname, sex, syear, major, avr)
VALUES (?,?,?,?,?,?)"
このように、構造のフレームは早めに入れて、値を付けるだけでいいのでprestimtの方が早いです.
重複動作を
  • for文で例示した.
  • package ex01.jdbcp.pstmt;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class PreparedStatementInsert {
    
    	static {
    		try { 
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    		} catch (ClassNotFoundException e) {
    
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String[] args) {
    
    		// 2. url, id, pass
    		String url = "jdbc:oracle:thin:@localhost:1521:xe";
    		String id = "bitTest";
    		String pass = "bitTest";
    
    		// 3. 클래스 변수 선언
    		Connection con = null; // 오라클 접속에 필요
    		PreparedStatement preStmt = null; // SQL문 실행에 필요
    		ResultSet rs = null; // Select문 결과값 저장에 필요
    		int cnt = 0 ;
    		
    		try {
    			// 4. 오라클 접속
    			con = DriverManager.getConnection(url, id, pass);
    
    			
    //			아래처럼 sql문의 기본 구조는 동일하고 
    //			?를 대신할 파라미터만 계속 변경되므로 
    //			이럴 경우 Statement보다 월등히 속도가 빠르다.
    			
    			// 5. 데이터 삽입
    			String strInsert = "INSERT INTO student (sno, sname, sex, syear, major, avr) VALUES (?,?,?,?,?,?)";
    			preStmt = con.prepareStatement(strInsert);
    			
    			for (int i = 0; i < 1000; i++) {
    				preStmt.setString(1, ""+i);    //i.toString() 이렇게 해도 문자열이 되어 들어감.(pk는 중복되면 안되니까 바꿔줌)
    				preStmt.setString(2, "공융");
    				preStmt.setString(3, "남");
    				preStmt.setInt(4, 4);
    				preStmt.setString(5, "화학");
    				preStmt.setDouble(6, 0.95);	
    			}
    			
    
    			cnt = preStmt.executeUpdate();
    			System.out.println(cnt + "개 행 적용");
    
    			// 6. 결과 검사
    			String strSelect = "SELECT * FROM student";
    			preStmt = con.prepareStatement(strSelect);
    			rs = preStmt.executeQuery();
    			int idx = 1;
    			while (rs.next()) { // next를 실행하는 순간 첫번째를 가리키게 된다.
    				System.out.println("--------[ " + idx + " ]---------");
    				System.out.println("sno : " + rs.getString(1));
    				System.out.println("sname : " + rs.getString(2));
    				System.out.println("sex : " + rs.getString(3));
    				System.out.println("syear : " + rs.getInt(4));
    				System.out.println("major : " + rs.getString(5));
    				System.out.println("avr : " + rs.getDouble(6));
    				idx++;
    			}
    
    		
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				// 7. 열린 객체 모두 닫기 , finally는 정상실행이든 예외가 발생하든 무조건 처리해준다.
    				// null이 아니라는 것은 정상실행되었다는 것이므로 닫아라.
    				if (rs != null) rs.close();
    				if (preStmt != null) preStmt.close();
    				if (con != null) con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    なぜ
  • の順序でデータを格納しないのですか?
  • 同时に多発している时に、先に出したものが停滞してしまいます.だから順番を変えて入ることができます.
    または、OracleDBは行の順序に関係なく...ランダムに保存することもできます.
    検索結果はorder byでコンソールウィンドウに順番に表示されます.
    Thread.また睡眠時間を与えたら順番に入りましょうか?
    package ex01.jdbcp.pstmt;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class PreparedStatementInsert {
    
    	static {
    		try { 
    			Class.forName("oracle.jdbc.driver.OracleDriver");
    		} catch (ClassNotFoundException e) {
    
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String[] args) {
    
    		// 2. url, id, pass
    		String url = "jdbc:oracle:thin:@localhost:1521:xe";
    		String id = "bitTest";
    		String pass = "bitTest";
    
    		// 3. 클래스 변수 선언
    		Connection con = null; // 오라클 접속에 필요
    		PreparedStatement preStmt = null; // SQL문 실행에 필요
    		ResultSet rs = null; // Select문 결과값 저장에 필요
    		int cnt = 0 ;
    		
    		try {
    			// 4. 오라클 접속
    			con = DriverManager.getConnection(url, id, pass);
    
    			
    //			아래처럼 sql문의 기본 구조는 동일하고 
    //			?를 대신할 파라미터만 계속 변경되므로 
    //			이럴 경우 Statement보다 월등히 속도가 빠르다.
    			
    			// 5. 데이터 삽입
    			String strInsert = "INSERT INTO student (sno, sname, sex, syear, major, avr) VALUES (?,?,?,?,?,?)";
    			preStmt = con.prepareStatement(strInsert);
    			
    			for (int i = 0; i < 1000; i++) {
    				preStmt.setString(1, ""+i);    //i.toString() 이렇게 해도 문자열이 되어 들어감.(pk는 중복되면 안되니까 바꿔줌)
    				preStmt.setString(2, "공융");
    				preStmt.setString(3, "남");
    				preStmt.setInt(4, 4);
    				preStmt.setString(5, "화학");
    				preStmt.setDouble(6, 0.95);	
    				
    				cnt = preStmt.executeUpdate();
    				System.out.println(cnt + "개 행 적용");
    				//Thread.sleep(10);  하나 보낼때마다 10ms(==0.01초)씩 쉬었다가 전송된다. 
    			}
    
    			// 6. 결과 검사
    			String strSelect = "SELECT * FROM student ORDER BY TO_NUMBER(sno)";
    			preStmt = con.prepareStatement(strSelect);
    			rs = preStmt.executeQuery();
    			int idx = 1;
    			while (rs.next()) { // next를 실행하는 순간 첫번째를 가리키게 된다.
    				System.out.println("--------[ " + idx + " ]---------");
    				System.out.println("sno : " + rs.getString(1));
    				System.out.println("sname : " + rs.getString(2));
    				System.out.println("sex : " + rs.getString(3));
    				System.out.println("syear : " + rs.getInt(4));
    				System.out.println("major : " + rs.getString(5));
    				System.out.println("avr : " + rs.getDouble(6));
    				idx++;
    			}
    
    		
    		} catch (SQLException e) {
    			e.printStackTrace();
    //		} catch (InterruptedException e){       -- thread로 인한 exception
    //			e.printStackTrace();
    		}finally {
    			try {
    				// 7. 열린 객체 모두 닫기 , finally는 정상실행이든 예외가 발생하든 무조건 처리해준다.
    				// null이 아니라는 것은 정상실행되었다는 것이므로 닫아라.
    				if (rs != null) rs.close();
    				if (preStmt != null) preStmt.close();
    				if (con != null) con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }