PreparedStatement

@IT:連載 基礎から学ぶサーブレット/JSP 第10回

また、セキュリティという意味からもPreparedStatementインターフェイスは有効です。というのも、PreparedStatementインターフェイスは実行時に渡されたパラメータをエスケープ処理します。つまり、もしも入力データにオリジナルのSQL命令を改ざんするような予約文字が混在していたとしても、PreparedStatementインターフェイスは内部的にこれを処理してくれるというわけです。昨今、問題視されるSQLインジェクションなどのセキュリティ対策という意味でも、積極的にPreparedStatementインターフェイスを使用することをお勧めします。


JavaAPI リファレンスにおいて,PreparedStatement の Statement に対する優位性は,同じ SQL 文を複数回実行するときに効率がよい,ということばかり強調されている.そのため,SQL 文を単発で使うときにはそれほど違いがない,むしろ,やや複雑になってしまう分 PreparedStatement の方が悪いようにさえ感じてしまう.
だが,実際は SQL 文に変数の内容を挿入するときに適切にエスケープしてくれる,という点で PreparedStatement はかなり使えるようだ.


例えば,String 型の変数 name に名前が入っているとき,以下のような SQL 文を発行したいとする.

SELECT * FROM table WHERE name = '名前'


通常の Statement では name の内容を適切にエスケープ(例えば ' とか \ とか)しなければ SQL の発行に失敗する可能性がある.

String sql = "SELECT * FROM table WHERE name = '" + name + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);


PreparedStatement では setString が name を ? の位置に挿入するときに勝手にエスケープしてくれる.

String sql = "SELECT * FROM table WHERE name = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
ResultSet rs = pstmt.executeQuery();