본문 바로가기
JAVA

[JAVA] JDBC - PreparedStatement

by Amy IT 2022. 6. 7.

자바에서 DB로 SQL문을 전송하고, DB에서 SQL문을 실행한 결과를 다시 자바로 받아오기 위해 Statement, PreparedStatement 또는 CallableStatement 인터페이스를 사용합니다. PreparedStatementStatement를 상속받는 인터페이스로서, 더 향상된 기능을 제공합니다. 

 

  • SQL문 작성시 작은따옴표를 자동으로 처리해 줍니다.
  • SQL문이 한 번 분석되면 캐시에 저장되기 때문에 재사용이 용이합니다.
  • SQL문이 미리 컴파일되기 때문에 Statement 보다 성능상 우위입니다.
  • 동적으로 SQL문을 처리할 수 있습니다. 즉, 동일한 SQL문에 다른 매개변수를 설정할 수 있습니다.
  • SQL injection(보안상 허점을 악용한 SQL문을 실행해 DB를 비정상적으로 조작)을 방어할 수 있습니다.

 

 

 

▶ 기본 사용법

 

  1. SQL문을 작성합니다. 특정 값을 지정해야 하는 위치에 물음표(?)를 표시해 줍니다.
  2. Connection 객체의 prepareStatement(String sql) 메소드를 이용해 PreparedStatement 객체를 생성합니다. Statement와 달리, 객체 생성시 SQL문을 인자로 전달합니다. 
  3. PreparedStatement 객체의 setXXX(int parameterIndex, XXX x) 메소드를 이용해 값을 설정합니다. 물음표의 인덱스값(1부터 시작)과 데이터 타입에 맞는 값을 인자로 전달합니다.
  4. PreparedStatement 객체의 executeQuery() 또는 executeUpdate() 메소드를 이용해 SQL문을 실행하고 결과값을 받습니다. 이때 SQL문을 인자로 전달하지 않는 점을 주의합니다. 

 

 

(1) SELECT

 

부서명이 SALES인 부서의 정보를 SELECT 해 보겠습니다.

import java.sql.*;
public class PreparedStatement_Test2 {
	public static void main(String[] args) {
		//1.변수 선언 및 초기화
		String driver = "oracle.jdbc.driver.OracleDriver";
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		String userid = "scott";
		String passwd = "tiger";
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {//2.드라이버 로드 
			Class.forName(driver);
			//3.DB 접속 
			con = DriverManager.getConnection(url, userid, passwd);
			//4.SQL문 작성
			String sql = "select deptno, dname, loc from dept where dname=?";
			//5.SQL문 실행 후 결과값 얻기
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, "SALES");
			rs = pstmt.executeQuery();
			//6.데이터 출력
			while (rs.next()) {
				int deptno = rs.getInt("deptno");
				String dname = rs.getString("dname");
				String loc = rs.getString("loc");
				System.out.println(deptno+"\t"+dname+"\t"+loc);
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs!=null) rs.close();
				if(pstmt!=null) pstmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

Statement 인터페이스를 사용할 경우, SALES 부서명을 설정할 때, SQL문에 작은따옴표를 신경써서 작성해야 하는 번거로움이 있었습니다. 하지만 PreparedStatement를 이용하면 SQL문에는 물음표로 위치를 표시한 후, set() 메소드를 이용해 값을 설정할 수 있게 됩니다. 각 물음표 위치의 데이터 타입만 맞게 설정하면 되고, 작은따옴표는 자동으로 붙여주기 때문에 훨씬 편리해 집니다. 

 

 

 

(2) INSERT

 

이번에는 66번 부서와 77번 부서를 INSERT 해 보겠습니다. 위와 동일한 코드에, "4.SQL문 작성" 부터 "6.데이터 출력" 까지의 코드만 변경하겠습니다. 

//4.SQL문 작성
String sql = "insert into dept (deptno, dname, loc) "
		+ " values (?, ?, ?)";
//5.SQL문 실행 
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, 66);
pstmt.setString(2, "개발");
pstmt.setString(3, "서울");
int num1 = pstmt.executeUpdate();
//같은 PreparedStatement 객체 이용
pstmt.setInt(1, 77);
pstmt.setString(2, "영업");
pstmt.setString(3, "경기");
int num2 = pstmt.executeUpdate();
System.out.println("변경된 레코드 개수: "+(num1+num2));

Statement 이용시 SQL문의 값이 하나라도 변경되면 새로 작성하여 SQL문을 실행해야 하는 번거로움이 있었습니다. 하지만 PreparedStatement를 이용하면 동일한 구조의 SQL문에 특정 값만 바꾸어 SQL문을 실행할 수 있게 됩니다. 

 

 

이상으로 PreparedStatement 인터페이스의 장점과 기본 사용법에 대해 알아보았습니다.

 

 

'JAVA' 카테고리의 다른 글

[JAVA] MyBatis 시작하기  (0) 2022.06.15
[JAVA] JDBC - DAO, DTO 패턴  (0) 2022.06.09
[JAVA] JDBC 기본 개념과 프로그래밍 단계  (0) 2022.06.06
[JAVA] 컬렉션 - Map 계열  (0) 2022.06.04
[JAVA] 컬렉션 - ArrayList  (0) 2022.06.02

댓글