エンタープライズ:特集 2003/11/28 15:30:00 更新


特集:第2回 実用サンプルコードで理解する「Struts」の基礎 (6/15)

DBCPを使ったデータベースへの書き込み

 データベースへの書き込み処理には、「オープンソースで作るJava+DB」で説明したのと同じ方法でもよいだろう。

 しかしここでは、より効率的な方法として、Jakarta Projectの「Commons DBCP」を利用した方法を挙げてみよう。このCommons DBCPは、データベースへのコネクションプーリングをサポートした汎用的なものであり、データベースアクセスのためのコンポーネントだ。

 コネクションプーリングとは、データベースへの接続を幾つか持続しておき、使い回すことを意味する。一般的に、データベースアプリケーションでは、ユーザーがWebページにアクセスして何か処理をするたびに、「データベースに接続」→「データベース処理」→「データベースから切断」という流れになるが、この「データベースに接続」と「データベースから切断」という個所は比較的時間を要する。このため効率が悪いのだ。

 そこでWebページの処理が終わった時にデータベースから切断するのではなくそのまま開いた状態にしておき、次のクライアントからのアクセスで再利用すればよい。「接続と切断がむやみに繰り返されることを防ぎ、パフォーマンス向上させるのがコネクションプーリング」だ。

DBCP Componentのインストール

 「DBCP Component」は、Javarta Projetctからダウンロードできる。ソースファイルとバイナリファイル版があるが、ここではバイナリファイル版を利用しよう。

 2003年11月7日現在はバージョン1.1であり、「commons-dbcp-1.1.tar.gz」(またはcommons-dbcp-1.1.zip)としてダウンロード可能だ。同ファイルをダウンロードし、展開すると「commons-dhcp-1.1.jar」ファイルが確認できる。このファイルは、Webアプリケーションのディレクトリ「WEB-INF/lib/」に配置しておこう。

DBCP Componentを利用するための定義

 DBCP Componentには幾つかのクラスがあるが、ここでは、最も基本的な「BasicDataSource」を利用する。StrutsでBasicDataSourceを使う場合には、「struts-config.xml」ファイルに、利用するデータベースや動作の定義は「data-source要素」として定義しておく。この具体的な定義は、List 6のようになる。

List 6■struts-config.xmlファイルにおけるDBCP Componentを使うための定義
1: <!-- ==================================== Data Source Configuration -->
2: <data-sources>
3: <data-source type="org.apache.commons.dbcp.BasicDataSource">
4: <set-property
5: property="driverClassName"
6: value="org.postgresql.Driver" />
7: <set-property
8: property="url"
9: value="jdbc:postgresql:sampledb" />
10: <set-property
11: property="username"
12: value="dbuser"/>
13: <set-property
14: property="password"
15: value="mypassword"/>
16: <set-property
17: property="maxActive"
18: value="10" />
19: <set-property
20: property="maxWait"
21: value="5000" />
22: <set-property
23: property="defaultAutoCommit"
24: value="true" />
25: <set-property
26: property="defaultReadOnly"
27: value="false" />
28: </data-source>
29: </data-sources>

 List 6、各設定の意味する内容をTable 1に示した。なお、BasicDataSourceにはTable 1に示した以外にも、多数のプロパティが用意されている。その詳細については、BasicDataSourceのAPIリファレンスを参照してほしい。

Table 1■BasicDataSourceの設定値
プロパティ
内     容
driverClassName 利用するJDBCドライバのクラス名。PostgreSQLを使うならば、org.postgresql.Driver
url JDBCドライバでアクセスするデータベースの名前
username データベースに接続するユーザー名
password データベースに接続するパスワード
maxActive コネクションプーリングとして保持する最大数。0の場合には制限なし
maxWait データベースへ接続するとき失敗と考えるまでの待ち時間(ミリ秒)。この時間が経過してもデータベースに接続できなければ例外が発生する。-1で無制限に待つことを示す
detaulfAutoCommit 自動コミットするかどうか
detaultReadOnly 読み込みのみであるかどうか

DBCP Componentを使ってデータベースアクセスする

 次にDBCP Componentを使ってデータベースにアクセスし、掲示板データベースに書き込むコードを示そう。下記、List 7の通りだ。

List 7■KeijiWriteAction.javaファイル
1: package sample.keiji;
2:
3: import org.apache.struts.action.*;
4: import org.apache.commons.dbcp.BasicDataSource;
5: import java.sql.*;
6: import javax.servlet.http.HttpServletRequest;
7: import javax.servlet.http.HttpServletResponse;
8:
9: public class KeijiWriteAction extends Action
10: {
11: public ActionForward execute(
12: ActionMapping mapping, ActionForm form,
13: HttpServletRequest request, HttpServletResponse response)
14: {
15: // キャストする
16: KeijiWriteForm kform = (KeijiWriteForm)form;
17:
18: javax.sql.DataSource dataSource;
19: Connection conn = null;
20: PreparedStatement stmt = null;
21:
22: try
23: {
24: // データソースを取得して開く
25: dataSource = getDataSource(request);
26: conn = dataSource.getConnection();

27: stmt = conn.prepareStatement(
28: "INSERT INTO Keiji " +
29: "(name, email, title, body, host)" +
30: "VALUES(?, ?, ?, ?, ?)");
31:
32: stmt.setString(1, kform.getUsername());
33: stmt.setString(2, kform.getEmail());
34: stmt.setString(3, kform.getTitle());
35: stmt.setString(4, kform.getMsg());
36: stmt.setString(5, request.getRemoteHost());
37:
38: int resultCnt = stmt.executeUpdate();
39: }
40: catch (SQLException e)
41: {
42: // エラー
43: getServlet().log("DB Error", e);
44: ActionErrors errors = new ActionErrors();
45: errors.add("dberrormsg",
46: new ActionError("dberror.msg", e.toString()));
47: saveErrors(request, errors);
48: }
49: finally
50: {
51: try
52: {
53: if (stmt != null)
54: {
55: stmt.close();
56: }
57: if (conn != null)
58: {
59: conn.close();
60: }
61: }
62: catch (SQLException e)
63: {
64: getServlet().log("DB Close Error", e);
65: }
66: }
67:
68: // 結果のページを返す
69: return mapping.findForward("success");
70: }
71: }

 List 7を見ると分かるように、データベースへのアクセス方法は、JDBCドライバを利用する方法と同じだ。異なるのはデータベースへ接続する部分である。

 DBCP Componentを使う場合には、次に挙げるよう25行目の「getDataSourceメソッド」を使い、DataSourceオブジェクトを得ればよい。

25: dataSource = getDataSource(request);

 そしてその後、26行目にあるようにgetConnectionメソッドを呼び出すと、データベースへの接続が得られる。

26: conn = dataSource.getConnection();

 この時に得られるデータベース接続は、コネクションプーリングのものだ。つまり、DBCP Componentによってデータベース接続が幾つかプーリングされ、その中のひとつが得られる。ここで得たデータベース接続は、closeメソッドを呼び出すとデータベースへの接続が切断されるのではなく、プーリングに戻されて次のデータベースアクセスで再利用される。

前のページ | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 次のページ

[大澤文孝,ITmedia]