バッチ処理でデータベースアクセスを効率化するJavaTips 〜JSP/サーブレット編

» 2004年06月22日 10時00分 公開
[山田祥寛@IT]

 「準備済みSQL命令でデータベースアクセスを効率化する」で紹介した「準備済みSQL命令」(PreparedStatement)は、「パラメータだけが異なる同一のSQL命令を繰り返し実行する場合」に便利ですが、まったく異なる複数のSQL命令を実行したいというケースでは、効果的なパフォーマンスを望むことはできません。

 「ストアドプロシージャでデータベースアクセスを効率化する」で紹介した「ストアドプロシージャ」(CallableStatement)は、「複雑なSQL命令を実行する場合」には便利ですが、MySQLのようにストアドプロシージャをサポートしていない一部のデータベースサーバ(現在開発中のMySQL 5.0ではサポート予定)では利用することができません。また、開発者はデータベースサーバごとにストアドプロシージャの構文を学習する必要があるため、敷居の高さも否定できません。

 では、もう1つの便利なテクニックとして、SQL命令のバッチ実行(executeBatchメソッド)を紹介します。これは、準備済みSQL命令やストアドプロシージャとは異なり、SQL命令をあらかじめ解析・コンパイルしておくことでデータベースアクセスの効率化を図るというものではありません。複数のSQL命令を実行する際に命令を1つ1つ順番に実行していくのではなく、いったん命令を蓄積しておき、後でまとめて実行するというテクニックです。こうすることにより、単発的に命令を発行するのに比べ、処理前後のオーバヘッドを軽減することができるので、実行効率を向上することができます。

解説

 それでは、executeBatchメソッドを利用してbooksテーブルへのデータの登録・更新を行うサンプルプログラムを下記に示します。

package to.msn.wings;

import java.io.IOException;
import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class BatchSql extends HttpServlet {
  public void doGet(HttpServletRequest request,HttpServletResponse response)
    throws ServletException,IOException {
    Connection db=null;
    Statement objSql=null;
    try {
      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.createStatement();
      objSql.addBatch("UPDATE books SET title='10日でおぼえるJakarta入門教室',price=2800 WHERE isbn='ISBN 4-7981-0439-6'");
      objSql.addBatch("UPDATE books SET price=1800 WHERE isbn='ISBN 4-7980-0611-4'");
      objSql.addBatch("INSERT books(isbn,title,price) VALUES('ISBN 4-7980-0575-4','今日からつかえるPHP4サンプル集 改訂版 ',2800)");

      objSql.executeBatch();
    } catch (ClassNotFoundException e) {
      throw new ServletException(e);
    } catch (SQLException e) {
      throw new ServletException(e);
    } finally {
      try {
        if(objSql!=null){objSql.close();}
        if(db!=null)    {db.close();}
      } catch(Exception e) {
        throw new ServletException(e);
      }
    }
  }
}


 サンプルプログラムを見ればわかるとおり、バッチ処理のロジックは、大まかに以下の2つの段階から構成されています。

  1. SQLコマンドをバッチ処理のスケジュールに追加(Statement#addBatchメソッド。赤字部分)
  2. バッチスケジュールに蓄積されたSQL命令を一括実行(Statement#executeBatchメソッド。緑字部分)

 なお、addBatchメソッドによってバッチ処理リストに追加された一連のSQLコマンドは、clearBatchメソッドでクリアすることができます。

注意:サーブレットクラスの動作にはデプロイメント・ディスクリプタ(web.xml)への登録が必須です。web.xmlの設定については、連載:基礎から学ぶサーブレット/JSP「第11回 JSPとサーブレットの違いを明らかにする」を参照してください。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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