✔️ SQL문을 실행할 때 사용하는 인터페이스
매번 쿼리를 수행할 때마다 4단계를 거치게 됨(계속적으로 단계를 거치면서 수행)
구문 분석(parse)부터 인출(fetch)까지 모든 과정을 매번 수행
➡️ 따라서 입력값에 SQL구문에 영향을 미치는 특수문자나 예약어가 들어갈 경우 구문 분석 과정에서 SQL구문의 일부로 작용하여 SQL Injection 공격이 가능하다.
➡️ 보안 취약
✔️ 데이터베이스 관리 시스템(DBMS)에서 동일하거나 비슷한 데이터베이스 문을 높은 효율성으로 반복적으로 실행하기 위해 사용되는 기능
구문 분석(parse) 과정을 최초 1회만 수행하여 생성된 결과를 메모리에 저장해 필요할 때마다 사용
미리 구성된 파싱 트리를 반복적으로 사용하기 때문에 Statement에 비해 시간을 단축할 수 있다.
SQL구문이 미리 컴파일 되어 사용자 입력값을 변수로 선언해 값을 대입하여 사용한다.
➡️ 외부 입력값으로 SQL문법에 영향을 미치는 특수문자나 예약어가 입력되어도 문법적인 의미로 작용하지 못한다.
➡️ 보안 향상
PreparedState를 사용하면 구문 분석(parse)의 결과를 캐싱해서 과정을 생략할 수 있으므로 성능이 향상된다.
✔️ 캐시(cache)사용여부에 따라 이 둘의 큰 차이점이 있다.
Statement를 사용하면 매번 쿼리를 수행할 때마다 4단계를 거치게 되고(계속적으로 단계를 거치면서 수행)
➡️ 성능 저하
➡️ SQL Injection 공격에 취약: 보안 취약
PreparedStatement는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용
: 만약 동일한 쿼리를 반복적으로 수행한다면 PreparedStatment가 DB에 훨씬 적은 부하를 줌
: SQL구문이 미리 컴파일 되어 사용자 입력값을 변수로 선언해 값을 대입하여 사용
➡️ 성능 향상
➡️ SQL Injection 공격 방어: 보안 향상
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
...
String sql = "SELECT * FROM MEMBER WHERE ID = '" + param_id + "' AND PW = '" + param_ passwd + "'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
String param_id = request.getParameter("id");
String param_passwd = request.getParameter("passwd");
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
…
String sql = "SELECT * FROM MEMBER WHERE ID = ? AND PW = ?";
pstmt.setString(1, param_id);
pstmt.setString(2, param_passwd);
rs = pstmt.executeQuery(sql);
Reference
: https://kpfis.or.kr/ko/major_biz/cyber_safety_oper/attack_info/security_news?articleSeq=2588