準備済みSQL命令は、その名のとおり、あらかじめ解析・コンパイルされた状態で「用意された」SQL命令のことです。通常のSQL命令を実行する場合、与えられたSQLコマンドは「解析→コンパイル→実行」という手順を踏まなければなりません。しかし、準備済みSQL命令では最初の実行時だけは通常のSQL命令と同様の手順ですが、2度目以降の実行時には「解析→コンパイル」の手順をスキップして、すぐに実行することができます。従って、後は実行時に必要なパラメータを渡すだけです。
このため、パラメータだけが異なる同一のSQL命令を繰り返し実行するようなケースでは、処理効率を大幅に向上させることができます。また、動的にセットされるパラメータは、あらかじめエスケープ処理されてからデータベースに渡されます。従って、パラメータの中にSQL命令に影響を与える「'」や「;」のような予約文字が含まれていても問題はありません。「SQLインジェクション」のようなセキュリティ上の問題を未然に防ぐという意味でも、準備済みSQL命令の活用は有効です。
Javaにおいて準備済みSQL命令の実行を実現するのは、PreparedStatementクラスの役割です。次に、サンプルコードを示します。
package to.msn.wings; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class PrepareSql extends HttpServlet { public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { Connection db=null; PreparedStatement objSql=null; try { request.setCharacterEncoding("Windows-31J"); Class.forName("org.gjt.mm.mysql.Driver"); db=DriverManager.getConnection("jdbc:mysql://localhost/ atit?user=root&password=root&useUnicode=true&characterEncoding=Windows-31J"); objSql=db.prepareStatement("UPDATE books SET title=?,price=? WHERE isbn=?"); for(int i=1;i<11;i++){ objSql.setString(1,request.getParameter("title" + i)); objSql.setString(2,request.getParameter("price" + i)); objSql.setString(3,request.getParameter("isbn" + i)); objSql.executeUpdate(); } } catch(Exception e) { throw new ServletException(e); } finally { try { if(objSql!=null){objSql.close();} if(db!=null) {db.close();} } catch(Exception e) { throw new ServletException(e); } } } }
あらかじめ用意されたSQL命令は、booksテーブルに対してisbnフィールドの値をキーとしてtitle、priceフィールドの値を更新するものです。このSQL命令に対してリクエストパラメータ「titleN」「priceN」「isbnN」(N:1〜10)を渡し、UPDATE文を10回繰り返し実行します。リストからの一括更新処理を行う場合などに便利な手法です。
注意:サーブレットクラスの動作にはデプロイメント・ディスクリプタ(web.xml)への登録が必須です。web.xmlの設定については、連載:基礎から学ぶサーブレット/JSP「第11回 JSPとサーブレットの違いを明らかにする」を参照してください。
Copyright © ITmedia, Inc. All Rights Reserved.