「準備済みSQL命令でデータベースアクセスを効率化する」でも紹介したとおり、準備済みSQL命令は、パラメータだけが異なる同一のSQL命令を繰り返し実行する場合には有効な手法です。しかし、準備済みSQL命令でも、1回目の実行に関しては通常のSQL命令と同様に「解析→コンパイル→実行」というステップを踏む必要があります。そのため、同一命令の繰り返しが行われないデータベースアクセスの場合は、必ずしも十分な効果をあげることができません。
そこで登場するのが、ストアドプロシージャです。ストアドプロシージャは、あらかじめ「データベースサーバ上に」用意されたSQL命令セットのことです。データベースサーバ上ですでに最適化されているので、実行に際してあらためて「解析→コンパイル」などの処理が発生することはありません。また、アプリケーションサーバとデータベースサーバとが別々のマシンの場合でも、パラメータの受け渡しだけで複雑なSQL命令がネットワーク上を行き来しないので、ネットワークによるボトルネックが発生する危険性を抑えることができます。
ストアドプロシージャは、CallableStatementクラスによって利用することができます。以下は、このCallableStatementクラスの使用例です。
package to.msn.wings;
import java.io.IOException;
import java.sql.CallableStatement;
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 CallableSql extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse
response)
throws ServletException,IOException {
Connection db=null;
CallableStatement objSql=null;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
db = DriverManager.getConnection("jdbc:odbc:sample", "usr", "pass");
objSql = db.prepareCall("{call InsertBook (?,?,?)}");
objSql.setString(1,"ISBN 4-7981-0439-6");
objSql.setString(2,"10日でおぼえるJakarta入門教室");
objSql.setString(3,"2800");
objSql.executeUpdate();
} 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 (SQLException se) {
throw new ServletException(se);
}
}
}
}
注意:使用しているデータベースサーバやバージョンによっては、CallableStatementクラス(ストアドプロシージャ)を利用できない場合もあるので注意してください。例えば、MySQL 4.0.xではストアドプロシージャの機能は提供されていません。
ストアドプロシージャInsertBookは、ISBNコード、書名、価格をパラメータとして受け取り、新規レコードを追加するためのものとします。ストアドプロシージャを呼び出す際は、以下のような構文を利用します。
{call ストアドプロシージャ名 (?,...)}
全体を{call 〜}で囲み、ストアドプロシージャ名とパラメータの数だけプレイスホルダである“?”を列記します。もしも、出力パラメータが存在する場合は、以下のように記述することも可能です。
{?=call ストアドプロシージャ名 (?,...)}
注意:サーブレットクラスの動作にはデプロイメント・ディスクリプタ(web.xml)への登録が必須です。web.xmlへの設定については、連載:基礎から学ぶサーブレット/JSP(11)「JSPとサーブレットの違いを明らかにする」を参照してください。
Copyright © ITmedia, Inc. All Rights Reserved.