これまでこの連載では、JSPを単独で用いる簡単なプログラムについて説明してきました。しかし、実際の業務アプリケーションの世界では、顧客情報や商品情報などを格納したデータベースとJSPの連携が必要になる場合が多いでしょう。今回は、JSPからデータベースを使用する方法について説明します。
現在は、数多くのデータベースソフトが存在し、どれを用いるかを決定することは悩ましい問題です。本稿では、フリーでありながら、非常に優れたデータベースソフトとして、Linux環境で広く使用されている、PostgreSQLを用いることにします。
本稿を執筆時現在、PostgreSQLの最新バージョンは7.1.3となっています。詳細は、PostgreSQLの公式サイトをご覧ください。
さて、データベースのセットアップには、JSPの環境構築と同様に若干の手間がかかります。スペースの都合上、ここではセットアップの手順についての説明は省かせていただきますが、Java Solutionフォーラムの連載記事「初めてのEnhydra」の第2回「データベース環境の構築」の中で、Linux環境でのPostgreSQLの構築方法が紹介されていますので、こちらをご覧ください。PostgreSQLは精力的にバージョンアップが行われているため、上記の記事で紹介されているバージョンは若干古いものとなっていますが、セットアップについては特に問題なく行えるはずです。うまくインストールできないなどの問題がある場合には、PostgreSQLに付属のドキュメントを参照するようにしてください。
JSPからデータベースへアクセスするためには、JDBCドライバが必要になります。上記の記事中に紹介されているように、ご自身でmakeして作成しても構いませんし、ここからPostgreSQL 7.0.x用の、Java2SEバージョンのものをダウンロードして使用することもできます。
PostgreSQLのセットアップが完了したら、さっそくデータを格納するためのテーブルを作成しましょう。テーブルの作成は、SQLのcreate table文で行えます。ここでは、メンバーIDと名前、および名前のヨミガナを含むmemberというテーブルを以下のようにして作成してみます。
create table member ( member_id serial primary key not null, name varchar(32) not null, kana varchar(32) not null );
上記のSQL文を直接入力しても構いませんし、一度create_member_table.sqlというようなファイルに保存し、コマンドラインで、
psql db_name < create_member_table.sql
として、ファイル内のSQL文を実行させても構いません(db_nameにはデータベース名を指定します)。
serialというデータ型は、自動的に番号を振っていく列を意味します。
さて、テーブルを作成したら、データを入力してみましょう。例えば次のようなSQL文により、4人分のメンバー情報を登録します(テーブルの作成とメンバー情報登録を行うSQL文はここからダウンロードできます)。
insert into member(name, kana) values ('JSP 太郎', 'ジェイエスピー タロウ'); insert into member(name, kana) values ('IT 次郎', 'アイティー ジロウ'); insert into member(name, kana) values ('山田 三郎', 'ヤマダ サブロウ'); insert into member(name, kana) values ('佐藤 四郎', 'サトウ シロウ');
うまく登録が行えたら、
select * from member;
と入力し、メンバー情報を確認してみましょう。次のように表示されたら、データベース側の準備は完了です。
member_id | name | kana -----------+-----------+----------------------- 1 | JSP 太郎 | ジェイエスピー タロウ 2 | IT 次郎 | アイティー ジロウ 3 | 山田 三郎 | ヤマダ サブロウ 4 | 佐藤 四郎 | サトウ シロウ (4 rows)
それでは、JSPからデータベースにアクセスするための作業を始めます。ところで、実はJSPから直接データベースにアクセスすることはできません。そのため、データベースにアクセスを行うオリジナルクラスまたはBeanを作成し、それをJSP側から使用することで間接的にデータベースにアクセスします。
1つの例として、データベースにアクセスするためのオリジナルクラス、MyDBAccessクラスを作成して、それを使用することにします。このMyDBAccessクラスのコードは次のようになります。
package atmarkit; import java.sql.*; public class MyDBAccess { private String driver; private String url; private String user; private String password; private Connection connection; private Statement statement; private ResultSet resultset; /** * コンストラクタ * @param driver ドライバー * @param url URL * @param user ユーザー名 * @param password パスワード */ public MyDBAccess(String driver, String url, String user, String password) { this.driver = driver; this.url = url; this.user = user; this.password = password; } /** * 引数なしのコンストラクタ * 既定値を使用する */ public MyDBAccess() { driver = "org.postgresql.Driver"; url = "jdbc:postgresql://localhost:5432/jspdb"; user = "postgres"; password = ""; } /** * データベースへの接続を行う */ public synchronized void open() throws Exception { Class.forName(driver); connection = DriverManager.getConnection(url, user, password); statement = connection.createStatement(); } /** * SQL 文を実行した結果の ResultSet を返す * @param sql SQL 文 */ public ResultSet getResultSet(String sql) throws Exception { if ( statement.execute(sql) ) { return statement.getResultSet(); } return null; } /** * SQL 文の実行 * @param sql SQL 文 */ public void execute(String sql) throws Exception { statement.execute(sql); } /** * データベースへのコネクションのクローズ */ public synchronized void close() throws Exception { if ( resultset != null ) resultset.close(); if ( statement != null ) statement.close(); if ( connection != null ) connection.close(); } }
オリジナルクラスの使用を解説した連載第6回の記事を参考に、上記のコードをコンパイルし、WEB-INF/classes/atmarkit以下に配置することで、このMyDBAccessクラスをJSP側から使用できるようにしましょう。
MyDBAccessクラスのコンストラクタには引数のないものと各種パラメータを指定できるコンストラクタの2つが準備されています。引数のあるコンストラクタ
MyDBAccess(String driver, String url, String user, String password)
では、データベースアクセス用のドライバ名、データベースアクセス用のURL、データベースへアクセスするユーザー名、およびパスワードを指定できます。
毎回データベースにアクセスするたびにこれらを指定するのは大変なので、各パラメータに固定の値を使用する、引数のないコンストラクタMyDBAccess()も作成しておきました。このコンストラクタでは、デフォルト値が次のようになっています。
34: driver = "org.postgresql.Driver"; 35: url = "jdbc:postgresql://localhost:5432/jspdb"; 36: user = "postgres"; 37: password = "";
ユーザー名、データベース名などはご自身の環境に合わせて変更する必要があります。このMyDBAccessクラスで定義されているメソッドは次のとおりです。
メソッド名 | 戻り値 | 説明 | |
---|---|---|---|
open() | void | データベースへの接続を行う | |
getResultSet(String sql) | ResultSet | SQL 文を実行した結果の ResultSet を返す | |
execute(String sql) | void | SQL 文を実行する | |
close() | void | データベースへのコネクションを閉じる | |
このようなメソッドを備えたクラスを作成しておくことで、JSPからデータベースにアクセスできるようになります。また、SQL文を実行するための煩雑な処理を次のような一連の流れで簡単に実行できるようになります。
MyDBAccess db = new MyDBAccess(); db.open(); db.execute(someSQL);// SQL文の実行 db.close();
MyDBAccess db = new MyDBAccess(); db.open(); ResultSet rs = db.getResultSet (someSQL);// SQL文を実行して結果を取得 db.close();
データベースへのコネクションの接続や解放など、毎回行う処理をMyDBAccessクラスでブラックボックス化することで、データベースへアクセスをシンプルな記述で実現することができます。
それでは、実際に上記のMyDBAccessクラスを使用して、JSPからデータベースにアクセスしてみます。次の例では、メンバーの一覧をmemberテーブルから取得し、その結果を表で表示します。
<%@ page import="java.sql.*, atmarkit.MyDBAccess" contentType="text/html; charset=euc-jp" %> <% // 内容: データベースにアクセスする // MyDBAccess のインスタンスを生成する MyDBAccess db = new MyDBAccess(); // データベースへのアクセス db.open(); // メンバーを取得 ResultSet rs = db.getResultSet("select * from member"); // メンバー一覧表示用のテーブル String tableHTML = "<table border=1>"; tableHTML += "<tr bgcolor=\"000080\"><td><font color=\"white\">メンバーID</font></td>" + "<td><font color=\"white\">名前</font></td>" + "<td><font color=\"white\">カナ</font></td>"; // 取得された各結果に対しての処理 while(rs.next()) { int id = rs.getInt("member_id"); // メンバーIDを取得 String name = rs.getString("name"); // メンバー名を取得 String kana = rs.getString("kana"); // メンバー名(カナ)を取得 // 文字コードを EUC_JP からUnicode へ変換 name = new String(name.getBytes("8859_1"), "EUC_JP"); kana = new String(kana.getBytes("8859_1"), "EUC_JP"); // テーブル用HTMLを作成 tableHTML += "<tr><td align=\"right\">" + id + "</td>" + "<td>" + name + "</td><td>" + kana + "</td></tr>"; } tableHTML += "</table>"; // データベースへのコネクションを閉じる db.close(); %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head><title>データベースへのアクセス</title></head> <body> <p>-- データベースへのアクセス --</p> <p> <b>メンバーの一覧</b><br> <%= tableHTML %> </p> </body> </html>
まず初めに、java.sqlのパッケージをインポートします。また、先ほど作成したMyDBAccessクラスもインポートしておきます。
<%@ page import=" java.sql.*, atmarkit.MyDBAccess" contentType="text/html; charset=euc-jp" %>
データベースへのアクセスと、SQL文の実行による結果を取得するには、6〜13行目のような一連の処理を行います。MyDBAccessクラスで処理が隠ぺい化されているので、次のような簡単な記述でSQL文の結果を取得することができます。
6: // MyDBAccess のインスタンスを生成する 7: MyDBAccess db = new MyDBAccess(); 8: 9: // データベースへのアクセス 10: db.open(); 11: 12: // メンバーを取得 13: ResultSet rs = db.getResultSet("select * from member");
SQL文からの取得結果であるResultSetから実際の値を取り出すには、次のように、while()ループでResultSetを巡回するようにします。
while(rs.next()) { /* ResultSet から値を取得 */ /* 取得した結果に対する処理 */ }
ResultSetから整数値を取得するには、以下のメソッドを使用します。
getInt(フィールド名)
また、文字列を取得するには、以下のメソッドを使用します。
getString(フィールド名)
また、今回の例では、文字列がEUC_JPコードで格納されているので、28〜30行目のような文字コードの変換が必要になります。
28: // 文字コードを EUC_JP からUnicode へ変換 29: name = new String(name.getBytes("8859_1"), "EUC_JP"); 30: kana = new String(kana.getBytes("8859_1"), "EUC_JP");
最後に、MyDBAccess クラスの close メソッドによって、データベースへのコネクションを閉じます。
39: // データベースへのコネクションを閉じる 40: db.close();
さて、以上のプログラムの実行結果は次のようになります。
データベースに格納したメンバーの一覧が表示されたことが確認できます。以上の方法で、JSPからデータベースにアクセスすることができました。
今回は、JSPからデータベースへアクセスするための方法を説明しました。次回はデータベースを用いて、より実際的なWebアプリケーションを1つ作成してみます。いままで続いてきた連載も、いよいよ次回で最終回になります。
Copyright © ITmedia, Inc. All Rights Reserved.