[Day 13 | DB] JDBC - PreparedStatement

y♡ding·2024년 10월 30일
0

데브코스 TIL

목록 보기
87/163

PreparedStatement는 자바의 JDBC에서 SQL 쿼리를 사전에 컴파일하여 파라미터를 동적으로 설정할 수 있도록 하는 객체입니다. 이 객체는 보안성과 성능을 높이는 데 유용하며, 특히 SQL 인젝션 공격을 방지하는 데 중요한 역할을 합니다.

PreparedStatement 사용 단계

  1. SQL 쿼리 작성: SQL 문을 준비할 때 파라미터 자리(?)를 미리 정의합니다.
  2. PreparedStatement 생성: Connection.prepareStatement() 메서드를 사용해 PreparedStatement 객체를 생성합니다.
  3. 파라미터 바인딩: 각 파라미터에 대해 타입에 맞는 setX() 메서드를 호출해 값을 설정합니다.
  4. 쿼리 실행: executeQuery()executeUpdate() 메서드를 사용해 쿼리를 실행합니다.

PreparedStatement 주요 메서드

* 파라미터 설정 메서드:

  • setInt(int parameterIndex, int x): 정수형 파라미터 설정
  • setString(int parameterIndex, String x): 문자열 파라미터 설정
  • setDouble(int parameterIndex, double x): 실수형 파라미터 설정
  • setDate(int parameterIndex, java.sql.Date x): 날짜형 파라미터 설정

* 쿼리 실행 메서드:

  • executeQuery(): SELECT 문 실행 (결과로 ResultSet 반환)
  • executeUpdate(): INSERT, UPDATE, DELETE 실행 (영향받은 행 수 반환)

PreparedStatement 활용 시 주의사항

  • 파라미터 인덱스: 1부터 시작하며, SQL 문의 ? 순서와 일치해야 합니다.
  • 자원 관리: 사용 후 PreparedStatementConnection은 반드시 close()를 호출하여 리소스를 반환합니다.
  • 예외 처리: SQL 실행 도중 발생할 수 있는 SQLException에 대비하여 적절히 예외를 처리하는 것이 좋습니다.

PreparedStatement의 특징과 장점

  • 보안성: 쿼리 파라미터가 SQL 문에 직접 포함되지 않고 바인딩되므로, SQL 인젝션 공격을 방지할 수 있습니다.
  • 성능 향상: PreparedStatement는 쿼리를 사전에 컴파일하고, 동일한 쿼리를 여러 번 실행할 때 재사용하므로 성능이 향상됩니다.
  • 유연한 파라미터 바인딩: 다양한 데이터 타입에 대해 setInt(), setString() 등으로 파라미터 값을 설정할 수 있습니다.

예제 코드

// insert
package com.exam;

import java.sql.*;

public class PreparedStatementEx01 {
    public static void main(String[] args) {
        System.out.println("시작");
		
        // 데이터베이스 URL, 사용자명, 비밀번호 설정
        String url = "jdbc:mariadb://localhost:3306/sample";
        String user = "root";
        String password = "123456";
		
        // Connection 및 PreparedStatement 객체 초기화
        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
        	// MariaDB JDBC 드라이버 로딩
            Class.forName("org.mariadb.jdbc.Driver");
            System.out.println("드라이버 로딩 성공");

			// 데이터베이스 연결 생성
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("데이터베이스 연결 성공");
			
            // SQL 쿼리를 준비한 PreparedStatement 객체 생성
            String sql = "insert into dept2 values (?, ?, ?)"; // 값만 물음표로 치환 가능(문자열X)
            pstmt = conn.prepareStatement(sql);

			// PreparedStatement에 각 파라미터 값 설정
            pstmt.setInt(1, 61);
            pstmt.setString(2, "영업부");
            pstmt.setString(3, "서울");

			// SQL 실행 및 데이터베이스에 삽입
            pstmt.executeUpdate(); // 괄호 안 공백 주의
            System.out.println("쿼리 실행 성공");

        } catch (ClassNotFoundException e) {
        	// 드라이버 로딩 실패 시 오류 메시지 출력
            System.out.println("[에러] " + e.getMessage());
        } catch (SQLException e) {
        	// SQL 관련 예외 발생 시 오류 메시지 출력
            System.out.println("[에러] " + e.getMessage());
        } finally {
        	// 객체 닫기
            if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) {}}
            if (conn != null) { try { conn.close(); } catch (SQLException e) {}}
        }

        System.out.println("끝");
    }
}
// update
package com.exam;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class PreparedStatementEx02 {
    public static void main(String[] args) {
        System.out.println("시작");

        String url = "jdbc:mariadb://localhost:3306/sample";
        String user = "root";
        String password = "exxyeon";

        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            System.out.println("드라이버 로딩 성공");

            conn = DriverManager.getConnection(url, user, password);
            System.out.println("데이터베이스 연결 성공");

            **String sql = "update dept2 set loc = ? where deptno = ?;";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "광주");
            pstmt.setString(2, "61");  // 61번을 광주로 바꿔줘

            int result = pstmt.executeUpdate();**

            System.out.println("쿼리 실행 성공");

        } catch (ClassNotFoundException e) {
            System.out.println("[에러] " + e.getMessage());
        } catch (SQLException e) {
            System.out.println("[에러] " + e.getMessage());
        } finally {
            if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) {}}
            if (conn != null) { try { conn.close(); } catch (SQLException e) {}}
        }

        System.out.println("끝");
    }
}
// select - ResertSet!! 
package com.exam;

import java.sql.*;

public class PreparedStatementEx03 {
    public static void main(String[] args) {
        System.out.println("시작");

        String url = "jdbc:mariadb://localhost:3306/sample";
        String user = "root";
        String password = "exxyeon";

        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            System.out.println("드라이버 로딩 성공");

            conn = DriverManager.getConnection(url, user, password);
            System.out.println("데이터베이스 연결 성공");

//            String sql = "select * from dept2";
            String sql = "select * from dept2 where deptno=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "51");
            rs = pstmt.executeQuery();

            while (rs.next()) {
                String deptno = rs.getString("deptno");
                String dname = rs.getString("dname");
                String loc = rs.getString("loc");
                System.out.println(deptno + "\t" + dname + "\t" + loc);
            }

            System.out.println("쿼리 실행 성공");

        } catch (ClassNotFoundException e) {
            System.out.println("[에러] " + e.getMessage());
        } catch (SQLException e) {
            System.out.println("[에러] " + e.getMessage());
        } finally {
            if (pstmt != null) { try { pstmt.close(); } catch (SQLException e) {}}
            if (conn != null) { try { conn.close(); } catch (SQLException e) {}}
        }

        System.out.println("끝");
    }
}

0개의 댓글

관련 채용 정보