日本語が使えたので、今度はDBアクセスです。オンラインマニュアルによると、MySQLを使うPHPの関数を使ってDBへアクセスできるようです。しかし、ここではJavaプログラマが一番興味を持つであろう、Pure Javaで動作させることを目標として、JDK 6に標準で同梱されているDerbyと連携させてみました。厳密に調べると、全部は必要ないはずですが、動作させることを優先して、resin-3.1.0/webapps/ROOT/WEB-INF/lib へDerbyのjarファイルを一式コピーしておきます。
編集部注:Derbyについての詳細を知りたい読者は、本連載第3回の「待望のJava SE 6 でパーシステンス」をご参照願います。
また、DB用にresin-3.1.0/dbディレクトリを作り、derby.properties設定ファイルを配置しておきます。なお、ここでは改良したResinを使って確認をしています。
$ mkdir ~/resin-3.1.0/webapps/ROOT/WEB-INF/lib
$ cp /usr/java/jdk1.6.0/db/lib/*.jar \
    /resin-3.1.0/webapps/ROOT/WEB-INF/lib/
derby.connection.requireAuthentication=true derby.authentication.provider=BUILTIN derby.user.adminuser=sapass
実際に使うDBのディレクトリとしてresin-3.1.0/db/sample/を作成してDerbyをサーバモードで起動しました。サーバ側はJDK 6同梱版なので、ここではJDK 6を使いました。別コンソールから起動している点には、注意してください。
$ export JAVA_HOME=/usr/java/jdk1.6.0 $ export DERBY_HOME=$JAVA_HOME/db $ cd ~/resin-3.1.0/db/ $ $DERBY_HOME/frameworks/NetworkServer/bin/startNetworkServer.ksh
サーバの起動ができたら、DBとテーブルの作成をする必要があります。ですから、新しくコンソールを開いて次のようにijコマンドを実行してサーバへ接続して、SQL文を実行しました。
$ export JAVA_HOME=/usr/java/jdk1.6.0 $ export DERBY_HOME=$JAVA_HOME/db $ $DERBY_HOME/frameworks/NetworkServer/bin/ij.ksh ij バージョン 10.2 ij> connect 'jdbc:derby://localhost/sampledb;create=true;user=adminuser; password=sapass'; ij> create table users ( id integer not null generated always as identity (start with 1, increment by 1), name varchar(20) ); 0 行が挿入/更新/削除されました
なお、Derbyを停止するには次のようにコンソールからコマンドを入力します。動作確認が終了した後は、このコマンドを入力してシャットダウンをするようにしましょう。
$ $DERBY_HOME/frameworks/NetworkServer/bin/stopNetworkServer.ksh
DerbyをPHPから使うためには、JNDIデータソースを登録する必要があります。webapps/ROOT/WEB-INF/resin-web.xmlを次のように作成しました。org.apache.derby.jdbc.ClientDriverを使って、ローカルホストのDerbyサーバへ接続するように設定をしています。PHPプログラムでこのデータソースを使う場合には、「jdbc/sampledb」というJNDI名を利用します。
<web-app xmlns="http://caucho.com/ns/resin"
        xmlns:resin="http://caucho.com/ns/resin/core">
    <database jndi-name='jdbc/sampledb'>
        <driver type="org.apache.derby.jdbc.ClientDriver">
            <url>jdbc:derby://localhost/sampledb</url>
            <user>adminuser</user>
            <password>sapass</password>
        </driver>
    </database>
</web-app>
編集部注:JNDIデータソースについての詳細を知りたい読者は、Java TIPSの「JNDI活用でデータソース管理を一元化する」をご参照願います。
結構手間が掛かりますが、準備をしてから、PDO(PHP Database Object)を使うPHPプログラムを作成して動作させてみました。最初は、検索がうまくできずに慌てましたが、DB側でカラム名が大文字になっていたので、それに合わせたところ動作するようになりました。insert.phpを1回表示してから、search.phpを表示すると、「テストユーザ」というデータが表示されます。
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; 
                charset=utf-8">
        <title>挿入テスト</title>
    </head>
    <body><p>
<?php
    $pdo = new PDO("java:comp/env/jdbc/sampledb","adminuser","sapass");
    echo "<h2>挿入 \$pdo->exec</h2>\n";
    $name = "テストユーザ";
    $pdo->exec("INSERT INTO users (NAME) VALUES ('$name')")
    || die("ユーザ $name を登録できませんでした");
?>
    </p></body>
</html>
「http://localhost:8080/insert.php」へアクセスすると、自動的に「テストユーザ」というNAMEの値を持つレコードがusersテーブルへ挿入されます。実行画面は次のとおりですし、実際にDBへ挿入されていることはijを起動したコンソールから確認できます。
ij> select * from users; ID |NAME -------------------------------- 1 |テストユーザ 1 行が選択されました
なお、検索にはいくつか方法がありますが、配列を使う方法、オブジェクトとして取得する方法のどちらも動作しました。「http://localhost:8080/search.php」へアクセスすると、DBに格納された値が表示されました。
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; 
                charset=utf-8">
        <title>挿入テスト</title>
    </head>
    <body><p>
<?php
    $pdo 
    = new PDO("java:comp/env/jdbc/sampledb","adminuser","sapass");
 
    echo "<h2>foreachで検索、配列を使用</h2>\n"; 
    echo "<table border='2'>\n";
    foreach ($pdo->query("SELECT * FROM users") as $row) {
        echo "<tr><td>${row['NAME']}</td></tr>\n";
    }
    echo "</table>\n";
 
    echo "<h2>whileで検索、配列を使用</h2>\n";
    $rs = $pdo->query("SELECT * FROM users");
    echo "<table border='2'>\n";
    while (($row = $rs->fetch(PDO::FETCH_ASSOC))) {
        echo "<tr><td>${row['NAME']}</td></tr>\n";
    }
    echo "</table>\n";
 
    echo "<h2>オブジェクトの使用</h2>\n";
    $rs = $pdo->query("SELECT * FROM users");
    echo "<table border='2'>\n";
    while (($obj = $rs->fetch(PDO::FETCH_OBJ))) {
        echo "<tr><td>$obj->NAME</td></tr>\n";
    }
    echo "</table>\n";
?>
    </p></body>
</html>
今回はResinに同梱されているPure JavaのPHP実行エンジンであるQuercusを使ってみました。また、Pure JavaのDBであるDerbyをResinで動作するPHPプログラムから使えることも確認してみました。オンラインマニュアルによると、JavaクラスをPHPプログラムから使用することもできるようなので、ほかにもいろいろなプログラミングが楽しめそうです。
さらに、オープンソースなら、今回紹介したように自分でソースコードを改良して使うことも可能です。腕に覚えのある人はパッチを作って本家へフィードバックをしてみるということもできるはずですが、まずはちょっとした改良から試してみると楽しいと思います。読者の皆さんも自分なりに使ってみてはいかがでしょうか?
参考
小山博史(こやま ひろし)
Webシステムの運用と開発、コンピュータと教育の研究に従事する傍ら、オープンソースソフトウェア、Java技術の普及のための活動を行っている。Ja-Jakartaプロジェクトへ参加し、コミッタの一員として活動を支えている。また、長野県の地域コミュニティである、SSS(G)やbugs(J)の活動へも参加している。
Copyright © ITmedia, Inc. All Rights Reserved.