Statement & PreparedStatement
Statement는 아래 예제처럼, DB에서 넘어오는 컬럼, 자바에서는 전송 객체의 멤버 변수명을
파라미터값에 직접 넣어주고 실행한다.
.. String col1 = request.getParameter("input1"); int col2 = request.getParameter("input2"); Statement stmt = null; .. try { .. String sql = "INSERT INTO table명(컬럼1, 컬럼2)" VALUES('col1', co2); .. } |
Prepared Statement는 컬럼, 자바에서는 전송 객체 멤버 변수명을 직접 넣지 않고, '?'로 작성하여
'?'의 위치 순번을 지정하여 실행한다.
.. String col1 = request.getParameter("input1"); int col2 = request.getParameter("input2"); Connection con = null; PreparedStatement pstmt = null; .. try { .. String sql = "INSERT INTO table명(컬럼1, 컬럼2)" VALUES(?, ?); pstmt = con.prepareStatement(sql); pstmt.setString(1, col1); pstmt.setString(2, col2); .. } |
두 클래스 모두 자바와 데이터베이스 연결후, SQL 쿼리를 전송해주는 역할을 하는 클래스인데
무엇 때문에 차이가 있다고 하는걸까?
단순히 개발자가 편의에 맞게 쓸 수 있도록 옵션을 두개 나눈 것일까?
결론부터 애기하자면, PreparedStatement는 Statement의 리소스 낭비와 SQL Injection 문제에
대응하기 위해 대체되는 클래스다.
조회를 예로들면, Statement는 1000번의 실행 계획을 갖고 반복할 경우 모든 전송 데이터값 일일히 넣어 실행해야하고,
쿼리문을 계속 재생성하기 때문에 데이터베이스에 부하를 주게 된다.
(다만, 처리량이 극히 낮은 경우는 Statement가 더 효율적이라고 한다.)
PreparedStatement는 처음에만 쿼리 실행 코드를 정의해놓고 실행시에만 값을 바꿔주고 그 이후로는
재사용하기 때문에 부하를 덜어주게 된다.
Injection으로 우려되는 케이스는 SQL의 변조등이 가능 할 수 있다는것이다.
sql변수에 쿼리문을 할당을 해놨는데 누군가가 문자열 사이에 엉뚱한 쿼리문을 작성하게 되면 큰 낭패를 볼 수 있다.
BEFORE ) String sql = "SELECT * FROM 테이블명; AFTER ) String Inject = "값'; DELETE FROM 테이블명;"; String sql = "SELECT * FROM 테이블명 WHERE 컬럼명 = '"+Inject"'"; |