連載
» 2004年05月18日 10時00分 公開

JavaTips 〜JSP/サーブレット編:準備済みSQL命令でデータベースアクセスを効率化する

[山田祥寛,@IT]

 準備済みSQL命令は、その名のとおり、あらかじめ解析・コンパイルされた状態で「用意された」SQL命令のことです。通常のSQL命令を実行する場合、与えられたSQLコマンドは「解析→コンパイル→実行」という手順を踏まなければなりません。しかし、準備済みSQL命令では最初の実行時だけは通常のSQL命令と同様の手順ですが、2度目以降の実行時には「解析→コンパイル」の手順をスキップして、すぐに実行することができます。従って、後は実行時に必要なパラメータを渡すだけです。

 このため、パラメータだけが異なる同一のSQL命令を繰り返し実行するようなケースでは、処理効率を大幅に向上させることができます。また、動的にセットされるパラメータは、あらかじめエスケープ処理されてからデータベースに渡されます。従って、パラメータの中にSQL命令に影響を与える「'」や「;」のような予約文字が含まれていても問題はありません。「SQLインジェクション」のようなセキュリティ上の問題を未然に防ぐという意味でも、準備済みSQL命令の活用は有効です。

解説

 Javaにおいて準備済みSQL命令の実行を実現するのは、PreparedStatementクラスの役割です。次に、サンプルコードを示します。

prepared.jsp
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.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。