Statement와 PreparedStatement의 차이

Statement

  1. 단일로 사용될 때 속도가 빠르다.
  2. 쿼리에 인자를 부여할 수 없다.
  3. 매번 컴파일을 수행해야 한다.

PreparedStatement

  1. 여러 번 수행될 때 속도가 빠르다.
  2. 쿼리에 인자를 부여할 수 있다.
  3. 처음 컴파일된 이후에는 컴파일을 다시 수행하지 않는다.
  4. Statement 클래스보다 기능이 향상된 클래스로, 코드의 안정성과 가독성이 높다.

 

Statement보다 PreparedStatement를 사용하는 것을 권장한다.

UPDATE문 작성 (Statement)

package day03;
import java.sql.*;
import java.util.Scanner;
/*
 * Statement를 이용하여
 * java_member테이블의 회원정보를 수정해봅시다
 * */
public class StatementTest1 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		System.out.println("수정할 회원의 ID 입력: ");
		String id = sc.nextLine();
		
		System.out.println("수정할 회원의 Name 입력: ");
		String name = sc.nextLine();
		
		System.out.println("수정할 회원의 Tel 입력: ");
		String tel = sc.nextLine();
		
		System.out.println("수정할 회원의 PW 입력: ");
		String pw = sc.nextLine();
		
		System.out.println(id+"/"+name+"/"+tel+"/"+pw);
		
		try {
			//1. driver 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("driver 클래스 로딩 성공!");
			//2. db 연동
			String user = "scott", password = "tiger";
			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			Connection con = DriverManager.getConnection(url, user, password);
			System.out.println("db연동 성공!");
			//3. SQL문 작성
			String sql = "UPDATE java_member SET name='" + name + "', tel='"
					+ tel + "', pw=" + pw + " WHERE id = '" + id + "'";
			System.out.println(sql);
			//4. Statement 객체 얻기
			Statement stmt = con.createStatement();
			//5. execute 쿼리 실행
			boolean b = stmt.execute(sql);
			System.out.println("b: " + b);
			//ResultSet 객체가 아니므로 false 반환
			
			//6. executeUpdate 쿼리 실행
			int re = stmt.executeUpdate(sql);
			System.out.println(re + "개 레코드 수정 완료!");
			//7.db자원 반납
			stmt.close();
			con.close();
			
		} catch(ClassNotFoundException e){
			e.printStackTrace();
		} catch(SQLException e) {
			e.printStackTrace();
		}
	}

}

 


UPDATE문 작성 (PreparedStatement)

package day03;
import java.sql.*;
import java.util.Scanner;
/*
 * PreparedStatement를 이용하여
 * java_member테이블의 회원정보를 수정해봅시다
 * */
public class PreparedStatementTest1 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		System.out.println("수정할 회원의 ID 입력: ");
		String id = sc.nextLine();
		
		System.out.println("수정할 회원의 Name 입력: ");
		String name = sc.nextLine();
		
		System.out.println("수정할 회원의 Tel 입력: ");
		String tel = sc.nextLine();
		
		System.out.println("수정할 회원의 PW 입력: ");
		String pw = sc.nextLine();
		
		System.out.println(id+"/"+name+"/"+tel+"/"+pw);
		
		try {
			//1. driver 로딩
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("driver 클래스 로딩 성공!");
			//2. db 연동
			String user = "scott", password = "tiger";
			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			Connection con = DriverManager.getConnection(url, user, password);
			System.out.println("db연동 성공!");
			//3. SQL문 작성
			//PreparedStatement 이용시에는 값에 해당하는 부분을 ? (in parameter)로 기술
			String sql = "UPDATE java_member SET name=?, tel=?, pw=? WHERE id=?";
			System.out.println(sql);
			//4. PreparedStatement 객체 얻기
			PreparedStatement pstmt = con.prepareStatement(sql);
			
			//5. PreparedStatement의 set 메서드를 사용하여 필요한 값을 지정
			//PreparedStatement 객체를 생성한 다음에는 PreparedStatement가 제공하는
			//set계열의 메서드를 사용하여 ? 를 대체할 값을 지정해 주어야 한다.
			//앞의 숫자는 ?의 순서이다.
			pstmt.setString(1, name);
			pstmt.setString(2, tel);
			pstmt.setString(3, pw);
			pstmt.setString(4, id);
			
			//6. execute 쿼리 실행
			boolean b = pstmt.execute();
			System.out.println("b: " + b);
			//ResultSet 객체가 아니므로 false 반환
			
			//7. executeUpdate 쿼리 실행
			int re = pstmt.executeUpdate();
			System.out.println(re + "개 레코드 수정 완료!");
			//8. db자원 반납
			pstmt.close();
			con.close();
			
		} catch(ClassNotFoundException e){
			e.printStackTrace();
		} catch(SQLException e) {
			e.printStackTrace();
		}
	}

}

 

 


예제를 통한 Statement와 PreparedStatement의 차이

1. 완성된 SQL문 vs 미완성된 SQL문

//<Statement>
//3. SQL문 작성
String sql = "UPDATE java_member SET name='" + name + "', tel='"
+ tel + "', pw=" + pw + " WHERE id = '" + id + "'";
//<PreparedStatement>
//3. SQL문 작성
String sql = "UPDATE java_member SET name=?, tel=?, pw=? WHERE id=?";
  • Statement는 변수나 값을 넣을 때 + 를 사용해야 돼서 가독성이 낮고, 코드의 길이가 길어진다.
    반면, PreparedStatement는 변수나 값에 해당하는 부분에 ? (in parameter)를 사용하므로 가독성이 높고, 코드의 길이가 짧다.
  • Statement의 SQL문은 완성된 SQL문인 반면, PreparedStatement의 SQL문은 미완성된 SQL문이다.
    PreparedStatement는 추후에 미완성 SQL문에 인자를 setString()으로 전달해야 한다.

 

2. 객체 생성

//<Statement>
//4. Statement 객체 얻기
Statement stmt = con.createStatement();
//<PreparedStatement>
//4. PreparedStatement 객체 얻기
PreparedStatement pstmt = con.prepareStatement(sql);
  • Statement는 객체 생성시 createStatement 메서드를 호출하고, 인자값이 없다.
  • PreparedStatement는 객체 생성시 prepareStatement 메서드를 호출하며, 인자값으로 미완성된 sql문이 전달된다.

 

3. Excute 쿼리 실행 전 - PreparedStatement

//<PreparedStatement>
//5. PreparedStatement의 set 메서드를 사용하여 필요한 값을 지정
//PreparedStatement 객체를 생성한 다음에는 PreparedStatement가 제공하는
//set계열의 메서드를 사용하여 ? 를 대체할 값을 지정해 주어야 한다.
//앞의 숫자는 ?의 순서이다.
pstmt.setString(1, name);
pstmt.setString(2, tel);
pstmt.setString(3, pw);
pstmt.setString(4, id);
  • SQL문 실행 전에 미완성된 문장을 PreparedStatement 클래스의 set 메서드로 채워준다.
  • PreparedStatement 객체를 생성한 다음에는 PreparedStatement가 제공하는 set 계열의 메서드를 사용하여 ? 를 대체할 값을 지정해 주어야 한다.
  • 앞의 숫자(1, 2, 3, 4)는 ?의 순서이다.
  • pstmt.setXXX(?의 위치, 실제값)

 

4. Excute 메서드 차이

//<Statement>
//5. execute 쿼리 실행
boolean b = stmt.execute(sql);
System.out.println("b: " + b);
//ResultSet 객체가 아니므로 false 반환
			
//6. executeUpdate 쿼리 실행
int re = stmt.executeUpdate(sql);
System.out.println(re + "개 레코드 수정 완료!");

 

//<PreparedStatement>
//6. execute 쿼리 실행
boolean b = pstmt.execute();
System.out.println("b: " + b);
//ResultSet 객체가 아니므로 false 반환
			
//7. executeUpdate 쿼리 실행
int re = pstmt.executeUpdate();
System.out.println(re + "개 레코드 수정 완료!");
  • Statement 클래스를 통한 SQL문 실행시 execute 메서드의 인자값으로 sql문을 전달한다.
  • PreparedStatement 클래스를 통해 SQL문을 실행하면 execute 메서드의 인자값은 비워둔다.

 


정리

Statement PreparedStatement
완성된 SQL문
String sql = " + "
미완성된 SQL문
String sql = " ?, ?, ? "
객체 생성시 createStatement 메서드 호출 (인자값 없음)
Statement stmt = con.createStatement();
객체 생성시 prepareStatement 메서드 호출
(미완성된 sql을 인자값으로 전달)
PreparedStatement pstmt = con.prepareStatememt(sql);
Statement 객체를 통한 SQL문 실행시

execute 메서드의 인자값으로 sql문 전달

stmt.executeXXX(sql);
SQL문 실행 이전, 미완성된 sql을 PreparedStatement 클래스의
set 메서드로 채워줌
pstmt.setString(?의 위치, 실제값)
pstmt.setInt(?의 위치, 실제값)

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

출처: https://mundol-colynn.tistory.com/48

+ Recent posts