準備済み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.