前へ     目次     索引     DocHome     次へ     
iPlanet Application Server 開発者ガイド



第 9 章   JDBC を使ったデータベースアクセス


この章では、Java Database Connectivity (JDBC) API を使って iPlanet Application Server でデータベースをアクセスする方法について説明します。この章では、iPlanet Application Server を使った Servlet および EJB への高度な JDBC の実装について説明します。また、iPlanet Application Server の特定のリソースが明らかにプログラミング分岐を持つ場合に JDBC ステートメントの影響を受けるそれらのリソースについて説明します。

iPlanet Application Server では、EJB は基本的に JDBC API を介したデータベースアクセスをサポートします。iPlanet Application Server は、リザルトセットの拡張、バッチ更新、分散トランザクション、行セット、データソース名の検索用の Java Naming and Directory Interface (JNDI) サポートなどの、さまざまな JDBC 2.0 拡張だけでなく、JDBC 2.0 API 全体をサポートします。



コンテナ、ローカル、またはグローバルのトランザクション管理は、固有のドライバでサポートされなくなりました。

iPlanet Application Server 6.0 SP1 では固有の JDBC ドライバのサポートが廃止されていましたが、このリリースでは下位互換性を維持するためにサポートされています。



この章では、JDBC 2.0 を十分に理解していることを前提とし、プログラミング分岐を持つ可能性がある特定の実装に関する問題についても説明します。たとえば、JDBC 仕様では、何が JDBC リソースを構成するかについては明確にされていません。この仕様では、データベースコネクションを閉じる Connection クラスメソッドなどの JDBC ステートメントには、それらのリソースが何であるかを正確に指定せずにリソースを解放するものもあります。

この章には次の節があります。



JDBC の紹介

プログラミングの観点からすると、JDBC はサーバアプリケーションにデータベース呼び出しを埋め込むことができる Java クラスおよびメソッドのセットです。サーバアプリケーションで JDBC を使い始めるには、このことだけを知っていれば十分です。

より厳密に言うと、JDBC は一連のインタフェースであり、iPlanet などのすべてのサーバベンダーは、JDBC 仕様に従ってこれを実装する必要があります。iPlanet Application Server には、さまざまな Enterprise Information System (EIS) データベースをサポートする JDBC タイプ 2 ドライバがあります。このドライバは、アプリケーションで JDBC ステートメントを処理し、その JDBC ステートメントに含まれている SQL 引数をデータベースエンジンに渡します。



JDBC を使うと、低レベルのデータベース実装を十分に理解していなくても、さまざまなデータベースでシームレスに操作できる、高度で使いやすいプログラムを記述することができます。


サポートされている機能



この節では、サポートに制限のある、固有の JDBC ドライバの機能について説明します。サードパーティの JDBC ドライバの機能については、そのドライバベンダーのドキュメントを参照してください。



JDBC 仕様書は、データベースベンダーに依存しない幅広い一連のガイドラインです。ガイドラインには、簡単なフレームワークで可能な広範のデータベース機能が含まれています。JDBC では、データベースが少なくとも SQL-2 データベースアクセス言語をサポートしていることを前提としています。JDBC 仕様書は 3 つの部分に分かれています。

  • JDBC 2.0 では、JDBC との互換性を維持するためにサーバベンダーが実装する必要のあるコアデータベースアクセスおよび機能について説明しています。iPlanet Application Server はこの基準を完全に満たしています。データベースベンダーの観点から、JDBC 2.0 では、標準 SQL-2 言語、各ベンダーがサポートする標準言語部分、および各ベンダーが実装する言語の拡張へのフルアクセスを許可するデータベースアクセスモデルについて説明しています。

  • JDBC 2.0 では、追加のデータベースアクセスおよび機能について説明しています。この機能には基本的に、新たに定義された SQL-3 機能、データタイプ、およびマッピングのサポートが含まれます。iPlanet Application Server への JDBC の実装によって、ほとんどの JDBC 機能拡張がサポートされますが、BLOBCLOB、アレイなどの新しい SQL-3 データタイプについてはサポートされません。現在、リレーショナルデータベース管理システムでこれらを完全にサポートしているデータベースベンダーは多くありません。iPlanet Application Server 版の JDBC でも、SQL-3 データタイプマッピングはサポートされません。

  • JDBC 2.0 Standard Extension API では、高度なサポート機能について説明しています。これらの機能によってデータベースのパフォーマンスが向上します。現在は、iPlanet Application Server への JDBC の実装によって、Java Naming and Directory Interface (JNDI) および行セットがサポートされます。


データベースの制約事項の理解

サーバアプリケーションで JDBC を使ったときに、望んだ結果や予期した結果が得られない場合があります。この場合、JDBC、または iPlanet Application Server への JDBC ドライバの実装に問題があると考えがちですが、この種の問題の原因の多くはデータベースエンジンの制約事項にあります。

JDBC は、可能なかぎり広範囲なデータベースサポートを扱うので、すべてのデータベースがサポートするとは限らないオペレーションを試みることもできます。たとえば、ほとんどのデータベースベンダーは SQL-2 言語の大部分をサポートしますが、どのベンダーも SQL-2 標準規格を制限付きでサポートします。ほとんどのベンダーは、既存の専用リレーショナルデータベース管理システムのトップに SQL-2 サポートを組み込みます。そして、専用のシステムが SQL-2 にない機能を提供するか、または SQL-2 が専用のシステムで利用できない機能を提供します。ほとんどのベンダーは、SQL の実装に非標準 SQL-2 拡張機能を追加することによって、ベンダー専用の機能をサポートしています。JDBC はベンダー固有の機能にアクセスする方法を提供しますが、使うデータベースによっては、これらの機能が利用できない場合があることを理解してください。

これは、複数のベンダーが提供するデータベースを使うアプリケーションを構築する場合に特に言えることです。つまり、すべてのベンダーが、利用可能な各 JDBC クラス、メソッド、およびメソッド引数のすべての機能を完全にサポートするとは限りません。さらに重要なことは、JDBC メソッド呼び出しに引数として埋め込まれた SQL ステートメントのセットが、サーバアプリケーションが使うデータベースによってサポートされたりサポートされなかったりする可能性があることです。JDBC を最大限に使うためには、データベースのマニュアルで、SQL および JDBC のどの特性がサポートされるかについて調べる必要があります。したがって、データベースの問題について iPlanet のテクニカルサポートに問い合わせる前に、まず問題の原因となっているデータベースを削除してください。


iPlanet Application Server の制約事項の理解

iPlanet Application Server は、JDBC のように、さまざまなデータベースエンジンおよび機能をサポートします。iPlanet Application Server 自体または iPlanet Application Server の JDBC ドライバが、特定のデータベース機能を完全にサポートできない場合があります。つまり、間違った情報がレポートされることがあります。iPlanet Application Server アプリケーションからデータベース機能にアクセスできない場合に、そのデータベースを削除しても問題が解消されない場合は、この節の説明およびリリースノートを読んで、発生した問題が iPlanet Application Server の制約事項として記載されているかどうかを調べます。その制約事項が問題の原因でない場合は、その問題を完全に記録した上で iPlanet テクニカルサポートまでご連絡ください。



JDBC アクセス問題には、iPlanet Application Server の JDBC ドライバに部分的にしかサポートされていない、またはまったくサポートされていない JDBC 機能にアクセスすることで発生するものもあります。機能の制約事項のほとんどすべてが JDBC 2.0 に適用されます。



表 9-1 は、iPlanet Application Server で部分的にしかサポートされていない、またはまったくサポートされていない JDBC 機能を示しています。


表 9-1    JDBC 機能の制約事項 

機能

制約事項

エスケープシーケンス  

Oracle データベース以外では使用できない  

Connection.setTransactionIsolation  

データベースベンダーによってサポートされている分離レベルだけを操作する  

Connection.getTypeMap  

タイプマップはサポートされていない  

Connection.setTypeMap  

タイプマップはサポートされていない  

Connection.cancel  

サポートするデータベースだけを操作する  

PreparedStatement.setObject  

シンプルデータタイプだけを操作する  

PreparedStatement.addBatch  

変更されたレコードの数を返す、サポートされているデータ操作ステートメントだけを操作する  

PreparedStatement.setRef  

参照はサポートされていない  

PreparedStatement.setBlob  

BLOB はサポートされていない。その代わりに setBinaryStream() を使う  

PreparedStatement.setClob  

CLOB はサポートされていない。その代わりに setBinaryStream() を使う  

PreparedStatement.setArray  

ARRAY はサポートされていないその代わりに setBinaryStream() を使う  

PreparedStatement.getMetaData  

サポートされていない  

CallableStatement.getObject  

スカラタイプだけを操作するJDBC 2.0 は、マップ引数が含まれるこのメソッドのセカンドバージョンを提供する。マップ引数は無視される  

CallableStatement.getRef  

参照はサポートされていない  

CallableStatement.getBlob  

SQL3 スタイル BLOB はサポートされていない  

CallableStatement.getClob  

SQL3 スタイル CLOB はサポートされていない  

CallableStatement.getArray  

ARRAY はサポートされていない  

CallableStatement  

更新可能な ResultSet はサポートされていない  

ResultSet.getCursorName  

データベースによって動作が異なる

Oracle では、ユーザが SetCursorName を使ってカーソル名を指定しない場合は空の文字列が返される

Sybase では、リザルトセットが更新不可能な場合は iPlanet Application Server によってカーソル名が自動的に生成される。それ以外は、空の文字列が返される

ODBC、Informix、および DB2 では、何も指定されない場合はドライバがカーソル名を返す  

ResultSet.getObject  

スカラタイプだけを操作するJDBC 2.0 は、マップ引数が含まれるこのメソッドのほかの 2 つのバージョンを提供する。マップ引数は無視される  

ResultSet.updateObject  

スカラタイプだけを操作する  

ResultSet.getRef  

参照はサポートされていない  

ResultSet.getBlob  

SQL3 スタイル BLOB はサポートされていない  

ResultSet.getClob  

SQL スタイル CLOB はサポートされていない  

ResultSet.getArray  

ARRAY はサポートされていない  

ResultSetMetaData.getTableName  

ODBC 以外のデータベースアクセスの場合は空の文字列を返す  

DatabaseMetaData.getUDTs  

サポートされていない  

行挿入後の executeUpdate  

DB2 の場合、1 の代わりに 0 を返す  

ResultSetResultSetMetaData、および PreparedStatement の操作の詳細については、この章の後続の節を参照してください。


サポートされるデータベース

iPlanet Application Server でサポートされるデータベースは定期的に更新されるので、データベースベンダーのアップグレードに従って、『iPlanet Application Server インストールガイド』または最新情報については『リリースノート』を参照してください。



6.x DD XML ファイルの 6.5 への移行



iPlanet Application Server 6.5 には、データベースコネクションの基盤に関連する機能の拡張が含まれています。この新しい機能を利用し、旧来のデータソースの設定を使い続けるには、新しいデータソース XML DTD に移行する必要があります。


6.x 配置記述子 XML ファイルへの移行

  1. 「ツール」 > 「データソースを登録」を選択します。

    データソースを登録するダイアログボックスが表示されます。

  2. 「開く」をクリックし、データソースの記述が含まれた XML ファイルを選択します。

    配置ツールによって、以前の XML ファイルにあった値がこの XML ファイルにインポートされ、6.5 で利用できるようになった新しいフィールドにデフォルトの値が入れられます。

  3. データソースのデフォルト値を受け入れるか、変更します。

  4. データベースドライバのパラメータ、コネクションプールのパラメータ、およびコネクション妥当性のパラメータを入力します。

    各フィールドの詳細については、『iPlanet Application Server 管理者ガイド』の第 8 章「データベース接続の管理」を参照してください。

  5. 「保存」をクリックします。

    配置ツールによって、指定した値のデータソース配置記述子が開いたファイルに上書きされます。

    注 : 更新された XML ファイルを別の名前で異なる場所に保存する場合は、「名前を付けて保存」を選択します。

  6. 「登録」をクリックします。

    配置ツールによって、データソース配置記述子が指定した新しい値で更新されます。これで、データソースは iPlanet Application Server 6.5 の新しい機能を利用できるようになります。



新規の XML データソース記述子

iPlanet Application Server 6.5 のトランザクションマネージャの基盤の変更とともに、データソース記述子も変更されました。新しい記述子には、さらに多くの機能とオプションがあります。

以下は、サードパーティドライバ用の XML データソース記述子の例です。


ローカルトランザクション

以下の XML ファイルの例は、iPlanet Application Server の IASConnectionPoolDataSource を使うデータベース用です。IASConnectionPoolDataSource は、データベース特有のドライバマネージャをラップします。


Oracle

<ias-resource>

  <resource>

    <jndi-name>jdbc/estore/EstoreDB</jndi-name>

    <jdbc>

      <user>estore</user>

      <password>estore</password>

      <URL> jdbc:oracle:thin:@192.18.117.186:1521:orcl</URL>

      <driver-name>oracle_xa</driver-name>

      <conn-pooling>

        <initialPoolSize>1</initialPoolSize>

        <waitQueueEnabled>true</waitQueueEnabled>

        <reclaimTime>600</reclaimTime>

        <maxPoolSize>30</maxPoolSize>

        <maxIdleTime>120</maxIdleTime>

        <queueLength>30</queueLength>

        <trace>disable</trace>

        <stat>disable</stat>

        <waitTimeInQueue>120</waitTimeInQueue>

        <tableBasedSanity>false</tableBasedSanity>

        <isSanityRequired>true</isSanityRequired>

        <incrementPoolSize>1</incrementPoolSize>

         <minPoolSize>1</minPoolSize>

     </conn-pooling>

    </jdbc>

  </resource>

</ias-resource>


Sybase

<ias-resource>

      <resource>

        <jndi-name>jdbc/estore/EstoreDB</jndi-name>

        <jdbc>

          <URL> jdbc:sybase:Tds:192.138.151.39:4444</URL>

          <user>estore</user>

          <password>estore</password>

          <driver-name>jconnect</driver-name>

          <conn-pooling>

            <initialPoolSize>1</initialPoolSize>

            <waitQueueEnabled>true</waitQueueEnabled>

            <reclaimTime>600</reclaimTime>

            <maxPoolSize>30</maxPoolSize>

            <maxIdleTime>120</maxIdleTime>

            <queueLength>30</queueLength>

            <trace>disable</trace>

            <stat>disable</stat>

            <waitTimeInQueue>120</waitTimeInQueue>

            <tableBasedSanity>false</tableBasedSanity>

            <isSanityRequired>true</isSanityRequired>

            <incrementPoolSize>1</incrementPoolSize>

            <minPoolSize>1</minPoolSize>

          </conn-pooling>

        </jdbc>

      </resource>

</ias-resource>


グローバルトランザクション

以下に示す XML ファイルの例は、ドライバ付属の XADataSource / ConnectionPoolDataSource (JDBC 2.0 + 拡張機能) を使うデータベースドライバ用です。アプリケーションでグローバルトランザクションとローカルトランザクションの両方を使う場合は、これらの XML フォーマットの使用をお勧めします。

すべてのデータソース XML ファイル内で、コネクションプールの要素 (conn-pooling) はオプションです。省略した場合は、デフォルト値が使用されます。詳細については、『iPlanet Application Server 管理者ガイド』を参照してください。XADatasource は、グローバルトランザクションが有効な場合にだけ使用されます。グローバルトランザクションの使用法については、『管理者ガイド』を参照してください。


DB2

<ias-resource>

    <resource>

        <jndi-name>jdbc/sample</jndi-name>

        <jdbc>

            <dataSourceName>friend</dataSourceName>

            <user>db2inst</user>

            <password>db2inst</password>

            <driver-name>db2_xa</driver-name>

            <databaseName>sample4</databaseName>

            <portNumber>50001</portNumber>

            <conn-pooling>

                <initialPoolSize>1</initialPoolSize>

                <waitQueueEnabled>true</waitQueueEnabled>

                <reclaimTime>600</reclaimTime>

                <maxPoolSize>30</maxPoolSize>

                <maxIdleTime>120</maxIdleTime>

                <queueLength>30</queueLength>

                <trace>disable</trace>

                <stat>disable</stat>

                <waitTimeInQueue>120</waitTimeInQueue>

                <tableBasedSanity>false</tableBasedSanity>

                <isSanityRequired>true</isSanityRequired>

                <incrementPoolSize>1</incrementPoolSize>

                <minPoolSize>1</minPoolSize>

            </conn-pooling>

        </jdbc>

    </resource>

</ias-resource>

Informix

<ias-resource>

  <resource>

    <jndi-name>jdbc/dshubble</jndi-name>

    <jdbc>

          <user>root</user>

          <datasourceName>rna_tcp</datasourceName>

          <databaseName>jts</databaseName>

          <serverName>rna_tcp</serverName>

          <portNumber>1528</portNumber>

          <ifxIFXHOST>rna</ifxIFXHOST>

          <password>abc123</password>

          <driver-name>ifx</driver-name>

<URL>jdbc:informix-sqli://rna:1528/sample:INFORMIXSERVER=rna_tcp</U RL>

          <conn-pooling>

                <initialPoolSize>1</initialPoolSize>

                <waitQueueEnabled>true</waitQueueEnabled>

                <reclaimTime>600</reclaimTime>

                <maxPoolSize>30</maxPoolSize>

                <maxIdleTime>120</maxIdleTime>

                <queueLength>30</queueLength>

                <trace>disable</trace>

                <stat>disable</stat>

                <waitTimeInQueue>120</waitTimeInQueue>

                <tableBasedSanity>false</tableBasedSanity>

                <isSanityRequired>true</isSanityRequired>

                <incrementPoolSize>1</incrementPoolSize>

                <minPoolSize>1</minPoolSize>

          </conn-pooling>

    </jdbc>

  </resource>

</ias-resource>


MSSQL

<ias-resource>

    <resource>

        <jndi-name>jdbc/sample</jndi-name>

        <jdbc>

            <dataSourceName>lancer</dataSourceName>

            <user>sa</user>

            <password></password>

            <driver-name>mssql</driver-name>

            <databaseName>master</databaseName>

            <networkProtocol>Tds</networkProtocol>

            <resourceManagerName>testrm</resourceManagerName>

            <serverName>lancer</serverName>

            <conn-pooling>

                <initialPoolSize>1</initialPoolSize>

                <waitQueueEnabled>true</waitQueueEnabled>

                <reclaimTime>600</reclaimTime>

                <maxPoolSize>30</maxPoolSize>

                <maxIdleTime>120</maxIdleTime>

                <queueLength>30</queueLength>

                <trace>disable</trace>

                <stat>disable</stat>

                <waitTimeInQueue>120</waitTimeInQueue>

                <tableBasedSanity>false</tableBasedSanity>

                <isSanityRequired>true</isSanityRequired>

                <incrementPoolSize>1</incrementPoolSize>

                <minPoolSize>1</minPoolSize>

            </conn-pooling>

        </jdbc>

    </resource>

</ias-resource>


Oracle

<ias-resource>

    <resource>

        <jndi-name>jdbc/sample</jndi-name>

        <jdbc>

            <URL>jdbc:oracle:oci8:@hubble</URL>

            <user>estore</user>

            <password>estore</password>

            <databaseName>hubble</databaseName>

            <driver-name>oracle_xa</driver-name>

            <conn-pooling>

                <initialPoolSize>1</initialPoolSize>

                <waitQueueEnabled>true</waitQueueEnabled>

                <reclaimTime>600</reclaimTime>

                <maxPoolSize>30</maxPoolSize>

                <maxIdleTime>120</maxIdleTime>

                <queueLength>30</queueLength>

                <trace>disable</trace>

                <stat>disable</stat>

                <waitTimeInQueue>120</waitTimeInQueue>

                <tableBasedSanity>false</tableBasedSanity>

                <isSanityRequired>true</isSanityRequired>

                <incrementPoolSize>1</incrementPoolSize>

                <minPoolSize>1</minPoolSize>

            </conn-pooling>

        </jdbc>

    </resource>

</ias-resource>


Sequelink

<ias-resource>

    <resource>

        <jndi-name>jdbc/sample</jndi-name>

        <jdbc>

            <datasourceName>mig</datasourceName>

            <user>kdemo</user>

              <password>kdemo</password>

            <driver-name>sequelink</driver-name>

            <databaseName>mig</databaseName>

            <serverName>mig</serverName>

            <portNumber>23003</portNumber>

            <URL>jdbc:sequeliik://mig:23003</URL>

            <conn-pooling>

                <initialPoolSize>1</initialPoolSize>

                <waitQueueEnabled>true</waitQueueEnabled>

                <reclaimTime>600</reclaimTime>

                <maxPoolSize>30</maxPoolSize>

                <maxIdleTime>120</maxIdleTime>

                <queueLength>30</queueLength>

                <trace>disable</trace>

                <stat>disable</stat>

                <waitTimeInQueue>120</waitTimeInQueue>

                <tableBasedSanity>false</tableBasedSanity>

                <isSanityRequired>true</isSanityRequired>

                <incrementPoolSize>1</incrementPoolSize>

                <minPoolSize>1</minPoolSize>

            </conn-pooling>

        </jdbc>

    </resource>

</ias-resource>


Sybase

<ias-resource>

    <resource>

    <jndi-name>jdbc/sample</jndi-name>

    <jdbc>

        <dataSourceName>prodigy</dataSourceName>

        <user>iplanet</user>

        <password>iplanet</password>

        <driver-name>sybase</driver-name>

        <databaseName>iplanet</databaseName>

        <networkProtocol>Tds</networkProtocol>

        <portNumber>4100</portNumber>

        <serverName>prodigy</serverName>

        <URL>jdbc:sybase:Tds:prodigy:4100</URL>

        <conn-pooling>

            <initialPoolSize>1</initialPoolSize>

            <waitQueueEnabled>true</waitQueueEnabled>

            <reclaimTime>600</reclaimTime>

            <maxPoolSize>30</maxPoolSize>

            <maxIdleTime>120</maxIdleTime>

            <queueLength>30</queueLength>

            <trace>disable</trace>

            <stat>disable</stat>

            <waitTimeInQueue>120</waitTimeInQueue>

            <tableBasedSanity>false</tableBasedSanity>

            <isSanityRequired>true</isSanityRequired>

            <incrementPoolSize>1</incrementPoolSize>

            <propertyCycle>0</propertyCycle>

            <minPoolSize>1</minPoolSize>

        </conn-pooling>

    </jdbc>

    </resource>

</ias-resource>



サーバアプリケーションでの JDBC の使用法



JDBC は iPlanet Application Server ランタイム環境の一部です。これは、Java を使ってアプリケーションをプログラミングするときには、常に JDBC が利用できることを意味します。典型的な多層サーバアプリケーションでは、Servlet 内および EJB 内で JDBC を使うと、クライアントやプレゼンテーションレイヤから EIS データベースにアクセスできます。

ただし、実際問題として、多層サーバアプリケーションの中間レイヤへのデータベースアクセスを制限することは、セキュリティおよび移植性に対して効果的です。iPlanet Application Server プログラミングモデルでは、これは EJB に対してプリファレンスを持つ Servlet および EJB に、すべての JDBC 呼び出しを配置することを意味します。

このプログラミングプリファレンスには 2 つの理由があります。

  • すべての JDBC 呼び出しを EJB 内部に配置すると、アプリケーションがさらにモジュール化され移植性が向上するため

  • EJB がトランザクション制御にビルトインメカニズムを提供するため

適切に設計された EJB に JDBC 呼び出しを配置すると、JDBC、または JDBC で低レベルトランザクションをサポートする java.transaction.UserTransaction を使った明示的なトランザクション制御をプログラミングする必要がありません。



EJB トランザクションマネージャがトランザクションを制御できるように、グローバルに利用できるデータソースを常に使って、グローバルな (Bean ワイドな) コネクションを作成してください。




EJB での JDBC の使用法

JDBC 呼び出しを EJB に配置すると、サーバアプリケーションの移植性が確実に向上します。これによって、明示的な JDBC 呼び出しを使ってトランザクション制御を管理する必要もなくなります。EJB はコンポーネントであるため、多数のアプリケーションでは、EJB をほとんど変更しないか、またはまったく変更しないビルディングブロックとして使って、EIS データベースへの共通のインタフェースを管理します。


JDBC または javax.transaction.UserTransaction によるトランザクションの管理

トランザクションの管理には、EJB トランザクション属性プロパティを使うことをお勧めしますがこれは必須ではありません。JDBC または javax.transaction.UserTransaction を使うトランザクション管理の明示的なプログラミングが、アプリケーションに適している場合があります。これらの場合、Bean 本体でトランザクション管理をプログラミングします。EJB で明示的なトランザクションを使うことを Bean 管理トランザクションと呼びます。

トランザクションは特定のメソッドに対してローカル (メソッド固有) になったり、または Bean 全体 (Bean ワイド) を含んだりします。

Bean 管理トランザクションを作成するには次の 2 つの手順があります。

  1. Bean の配置記述子で EJB の Transaction Type プロパティを Bean に設定します。

  2. トランザクションを起動、コミットまたはロールバックするステートメントを含む、適切な JDBC またはトランザクション管理ステートメントを Bean でプログラミングします。

Transaction Type プロパティが Bean 以外の場合、EJB に明示的なトランザクション処理をプログラミングしないでください。JDBC を使ったトランザクション処理の詳細については、JDBC 2.0 API 仕様書を参照してください。


トランザクションの分離レベルの指定

setTransactionIsolation() および getTransactionIsolation() メソッドをそれぞれ使って、コネクションのトランザクションレベルの指定または確認を行います。トランザクションの途中で setTransactionIsolation() を呼び出すことはできないので注意してください。

表 9-2では、次のようにトランザクション分離レベルを定義します。


表 9-2    トランザクション分離レベル

トランザクション分離レベル

説明

TRANSACTION_NONE  

トランザクションはサポートされない。Connection.getTransactionIsolation() だけで使われる  

TRANSACTION_READ_COMMITTED  

不正な読み込みを防ぐ。再現しない読み込みとファントム読み込みが発生する可能性がある  

TRANSACTION_READ_UNCOMMITTED  

不正な読み込み、再現しない読み込み、およびファントム読み込みが発生する可能性がある  

TRANSACTION_REPEATABLE_READ  

不正な読み込みと再現しない読み込みを防ぐ。ファントム読み込みが発生する可能性がある  

TRANSACTION_SERIALIZABLE  

不正な読み込み、再現しない読み込み、およびファントム読み込みを防ぐ  

Bean のトランザクション分離レベルを指定する前に、データベース管理システムがそのレベルをサポートしていることを確認してください。すべてのデータベースがすべての分離レベルをサポートするとは限りません。次の例のように、java.sql.DatabaseMetaDatasupportsTransactionIsolationLevel() メソッドを使うことによって、プログラムでデータベースをテストできます。

java.sql.DatabaseMetaData db;
if (db.supportsTransactionIsolationLevel(TRANSACTION_SERIALIZABLE) {
   Connection.setTransactionIsolation(TRANSACTION_SERIALIZABLE);
}

これらの分離レベルとその意味の詳細については、JDBC 2.0 API 仕様書を参照してください。


Servlet 内での JDBC の使用法

Servlet は iPlanet Application Server アプリケーションの中枢です。Servlet は、ブラウザ上の HTML ページや HTML を生成する JSP などのクライアントインタフェースと、アプリケーションの大部分の動作を実行する EJB の間に位置しています。

iPlanet Application Server アプリケーションは、EJB に埋め込まれた JDBC を使ってほとんどのデータベースにアクセスします。これは、iPlanet Application Server を使ったデータベースアクセスに最適なメソッドです。なぜなら、これによって EJB およびそのコンテナに組み込まれているトランザクション制御を利用できるからです。しかし、Servlet を使っても、JDBC を介してデータベースにアクセスできます。

Servlet から直接データベースにアクセスすると、EJB からデータベースにアクセスするよりも高速になる場合があります。EJB は Java Remote Method Interface (RMI) 経由でだけアクセス可能なため、アプリケーションが複数のサーバに分散している場合は、呼び出しのオーバーヘッドが小さくなります。Servlet からの直接データベースサービスを多用しないでください。Servlet からのデータベースアクセスを提供する場合は、アクセス時間が非常に短く、トランザクションが読み取り専用で、JDBC 2.0 の RowSet クラスを利用できる状況へのアクセスに制限されます。

データベースへのアクセスが Servlet からの場合は、JDBC 2.0 の RowSet インタフェースを使ってデータベースと対話してください。行セットは、データベースまたはスプレッドシートなどのほかの表形式データソースから取得した一連の行をカプセル化する Java オブジェクトです。RowSet インタフェースは、データソースに接続して一連の行を取得するように RowSet インスタンスを設定できる JavaBeans プロパティを提供します。行セットの操作方法の詳細については、「RowSet の操作」の節を参照してください。



コネクションの処理



iPlanet Application Server は、JDBC 2.0 互換インタフェース java.sql.Connection を実装しています。コネクションの動作は、コネクションがローカルか、グローバルか、またはコンテナ管理ローカルコネクションかによって異なります。


ローカルコネクション

Connection オブジェクトは、トランザクションコンテキストが EJB コンテナによって管理されていない場合はローカルコネクションと呼ばれます。ローカルコネクションのトランザクションコンテキストは、複数のプロセスまたはデータソース全体に伝播させることができません。つまり、現在のプロセスおよび現在のデータソースに対してローカルです。

このコネクションのタイプのトランザクションコンテキストは、setAutoCommit()commit()、および rollback() メソッドを使って管理されます。


ローカルデータソースの登録

ローカルコネクションを作成するには、まず iPlanet Application Server にデータソースを登録します。データソースを登録すると、登録したそのデータソースを使って、getConnection() を使って一覧表示されたデータベースに接続できます。

データソースの登録は、データソースのプロパティを記述する XML リソース記述子ファイルを作成することによって行います。次に、管理ツール、または resreg ユーティリティを使って、iPlanet Application Server にプロパティを登録します。resreg はデータソースを記述するリソース記述子ファイル名を引数と見なします。



実行中、resreg は既存のエントリを上書きします。



たとえば、ユーザ名 kdemo、パスワード kdemo、データベース ksample、およびサーバ ksample を使って、Oracle データベースに接続する SampleDS と呼ばれるデータソースを登録するには、次のような XML 記述子ファイルを作成して、SampleDS.xml という名前を付けます (この XML ファイルは iPlanet Application Server 配置ツールを使って作成します)

<ias-resource>
   <resource>
       <jndi-name>jdbc/SampleDS</jndi-name>
       <jdbc>
          <database>ksample</database>
          <datasource>ksample</datasource>
          <username>kdemo</username>
          <password>kdemo</password>
          <driver-type>ORACLE_OCI</driver-type>
       </jdbc>
   </resource>
</ias-resource>

次に、次のコマンドによって、このリソース記述子ファイルを使ってデータソースを登録します。

resreg SampleDS.xml

リソース記述子ファイルの詳細については、第 11 章「配置のためのパッケージ化」を参照してください。iPlanet Application Server 管理ツールの詳細については、『管理者ガイド』を参照してください。


グローバルコネクション

Connection オブジェクトは、トランザクションコンテキストが EJB コンテナによって管理されている場合はグローバルコネクションと呼ばれます。グローバルコネクションのトランザクションコンテキストは、データソース全体に伝播させることができます。コンテナ管理トランザクションの場合、トランザクションコンテキストは EJB コンテナによって暗黙的に管理され、Bean 管理トランザクションの場合は明示的に管理されます。トランザクションの詳細については、第 8 章「EJB のトランザクション処理」を参照してください。

たとえば、setAutoCommit()commit()rollback() などのトランザクション管理メソッドは、グローバルコネクションでは無効です。


グローバルデータソースの登録

グローバルコネクションを作成するには、まず iPlanet Application Server にデータソースを登録します。データソースを登録したら、そのデータソースを使って、getConnection() を使って一覧表示されるデータベースに接続します。

データソースの登録は、データソースのプロパティを記述する XML リソース記述子ファイルを作成することによって行います。次に、管理ツール、または resreg ユーティリティを使って、iPlanet Application Server にプロパティを登録します。resreg はデータソースを記述するリソース記述子ファイル名を引数と見なします。



実行中、resreg は既存のエントリを上書きします。



たとえば、ユーザ名 kdemo、パスワード kdemo、データベース ksample、およびサーバ ksample を使って、Oracle データベースに接続する GlobalSampleDS と呼ばれるデータソースを登録するには、次のような XML 記述子ファイルを作成して、GlobalSampleDS.xml という名前を付けます (この XML ファイルは iPlanet Application Server 配置ツールを使って作成)

<ias-resource>
   <resource>
       <jndi-name>jdbc/
GlobalSampleDS</jndi-name>
       <jdbc>
          <database>ksample</database>
          <datasource>ksample</datasource>
          <username>kdemo</username>
          <password>kdemo</password>
          <driver-type>ORACLE_OCI</driver-type>
          <resource-mgr>ksample_rm</resource-mgr>
       </jdbc>
   </resource>
</ias-resource>

次のコマンドによって、このリソース記述子ファイルを使ってデータソースを登録します。

resreg GlobalSampleDS.xml

リソース記述子ファイルの詳細については、第 11 章「配置のためのパッケージ化」を参照してください。iPlanet Application Server 管理ツールの詳細については、『管理者ガイド』を参照してください。


グローバルコネクションの作成

次のプログラムは、データソースを検索し、そのデータソースからコネクションを作成する方法を示します。ここに示されているように、検索される文字列はリソース記述子ファイル内の <jndi-name> タグに指定されるものと同じです。

InitialContext ctx = null;
String dsName1 = "jdbc/
GlobalSampleDS";
DataSource ds1 = null;

try
{
   ctx = new InitialContext();
   ds1 = (DataSource)ctx.lookup(dsName1);

   UserTransaction tx = ejbContext.getUserTransaction();

   tx.begin();

   Connection conn1 = ds1.getConnection();

   // データベースの作業には conn1 を使います。conn1.commit()、
   // conn1.rollback()、および conn1.setAutoCommit() はここでは使用でき ないので注意してください。

   tx.commit();

} catch(Exception e) {
   e.printStackTrace(System.out);
}


コンテナ管理ローカルコネクション

トランザクションコンテキストが EJB コンテナによって管理され、グローバルトランザクションが無効になっている場合、Connection オブジェクトはコンテナ管理ローカルコネクションであると考えられます。コンテナ管理トランザクションの場合、トランザクションコンテキストは EJB コンテナによって暗黙的に管理され、Bean 管理トランザクションの場合には明示的に管理されます。

Connection オブジェクトメソッド setAutoCommit()commit()、および rollback() は、このタイプのコネクションでは無効です。

EJB コンテナ内でグローバルトランザクションを有効または無効にする方法については、『管理者ガイド』を参照してください。


コンテナ管理ローカルデータソースの登録

コンテナ管理ローカルデータソースの登録プロセスは、ローカルおよびグローバルデータソースと同じです。詳細については、「ローカルデータソースの登録」を参照してください。



JDBC 機能の操作



この章では JDBC については説明しませんが、iPlanet Application Server で、EJB に JDBC を使う方法を紹介します。次の節では、さまざまな JDBC インタフェースおよびクラスについて説明します。これらのインタフェースおよびクラスには、iPlanet Application Server 環境に特定の必要条件があるか、または iPlanet Application Server アプリケーションの開発時に特に有益な新しい JDBC 2.0 機能があります。

たとえば、「コネクションの操作」では JDBC の実装ごとに情報が異なるため、コネクションを閉じるときに iPlanet Application Server が解放するリソースについて説明します。また、「コネクションのプール」および「RowSet の操作」では、能力、柔軟性、およびサーバアプリケーションの速度を高める新しい JDBC 2.0 機能についてより詳しく説明します。

この節には次のトピックがあります。


コネクションの操作

JDBC コネクションを開くと、iPlanet Application Server はそのコネクションリソースを割り当てます。コネクションが不要になったときに Connection.close() を呼び出すと、そのコネクションリソースが解放されます。Connection.close() を呼び出したあとに継続してデータベース操作を行うには、その前に必ずコネクションを確立し直してください。

Connection.isClose() を使って、コネクションが閉じているかどうかをテストします。このメソッドは、コネクションが開いていると false を返し、Connection.close() が呼び出された場合だけ true を返します。閉じたコネクションで JDBC オペレーションを行うとスローされる例外を見つけることによって、データベースコネクションが不正かどうかを調べます。

最後に、コネクションの開閉には時間がかかります。アプリケーションが複数のコネクションを使う場合や、コネクションを頻繁に開いたり閉じたりする場合、iPlanet Application Server は自動的にコネクションをプールします。コネクションをプールすると、必要に応じて自動的に閉じるコネクションのキャッシュが生成されます。



コネクションのプールは iPlanet Application Server の自動的な機能です。API は公開されていません。




setTransactionIsolation
すべてのデータベースベンダーが、JDBC で利用できるすべてのトランザクション分離レベルをサポートしているわけではありません。iPlanet Application Server を使うと、ユーザのデータベースサポートの任意の分離レベルを指定できますが、iPlanet Application Server はユーザのデータベースがサポートしていない値に対する例外をスローします。詳細については、「トランザクションの分離レベルの指定」を参照してください。


getTypeMap、setTypeMap
固有の JDBC ドライバが実装された iPlanet Application Server は、新しい SQL-3 機能であるタイプマッピングをサポートしません。この機能は、ほとんどのデータベースベンダーがサポートしていません。


cancel
cancel() は、cancel() をサポートするすべてのデータベースでサポートされています。


コネクションのプール

JDBC で実行する 2 つのデータベース操作、データベースコネクションの作成および破棄には時間がかかります。コネクションをプールすると、1 つのコネクションキャッシュをコネクションリクエストに使用できます。コネクションは実際には破棄されずに、あとで再利用するためにプールに戻されます。コネクションを作成するためにあとで呼び出すと、プールから利用可能なコネクションを取得します。

JDBC 呼び出しを作成すると、iPlanet Application Server は常に自動的に JDBC コネクションをプールします。データベースコネクションをプールするプロセスは、コネクションのタイプによって動作が異なります。

  • ローカルコネクションの場合、データベースコネクションはアプリケーションによって閉じられたときにプールされます。

  • グローバルコネクションの場合、データベースコネクションはトランザクションを開始したスレッドに接続されます。これらのコネクションはスレッドで実行するトランザクションによってあとで再利用されます。

  • コンテナ管理ローカルコネクションの場合、connection.close() メソッドはコネクションをコネクションプールにすぐに解放しません。コネクションが関係しているトランザクションが終了すると、コネクションは iPlanet Application Server によって解放され、コネクションプールに戻されます。

それぞれの Java エンジンには、各ドライバ (Oracle、Sybase、Informix、および DB2) にそれぞれのコネクションプールがあります。それぞれのコネクションプールのサイズは、アプリケーションの要件によって異なります。コネクションプールの設定 (コネクションの最大数やコネクションタイムアウトなど) の詳細については、『管理者ガイド』を参照してください。


ResultSet の操作

ResultSet は、データベースクエリによって返されるデータをカプセル化するクラスです。このクラスに関連する次の動作または制約事項に注意してください。



この節では、固有の JDBC ドライバの機能について説明します。サードパーティの JDBC ドライバによってサポートされるオプションについては、そのドライバベンダーのドキュメントを参照してください。




同時性のサポート

iPlanet Application Server は、FORWARD-ONLY READ-ONLY および SCROLL-INSENSITIVE READ-ONLY リザルトセットの同時性をサポートしています。呼び出し可能なステートメントでは、iPlanet Application Server は FORWARD-ONLY UPDATABLE リザルトセットの同時性もサポートしています。

SCROLL-SENSITIVE の同時性はサポートされていません。


更新可能なリザルトセットのサポート

iPlanet Application Server では、更新可能なリザルトセットの作成は 1 つのテーブルのクエリに限定されます。更新可能なリザルトセットの SELECT クエリには、FOR UPDATE 句を含む必要があります。

SELECT...FOR UPDATE [OF column_name_list]



ジョインを使って複数のテーブルに対して読み取り専用のリザルトセットを作成できますが、これらのリザルトセットは更新できません。



Sybase では、選択リストに固有のインデックス列が必要です。Sybase を使うと、execute() または executeQuery() を呼び出して更新可能なリザルトセットも作成できます。ただし、ほかの SQL ステートメントを実行する前に、このステートメントを閉じる必要があります。

Oracle 8 で更新可能なリザルトセットを使うには、次のようにトランザクションでリザルトセットクエリをラップする必要があります。

conn.setAutoCommit(false);
ResultSet rs =
   stmt.executeQuery("SELECT...FOR UPDATE...");
...
rs.updateRows();
...
conn.commit();

Microsoft SQL Server では、リザルトセットの同時性が CONCUR_UPDATABLE の場合、execute() または executeQuery() メソッドの SELECT ステートメントに ORDER BY 句を含めないでください。


getCursorName
リザルトセットメソッドの 1 つである getCursorName() を使うと、リザルトセットをフェッチするために使われるカーソル名を調べることができます。カーソル名がクエリ自体で指定されていない場合は、さまざまなデータベースベンダーがさまざまな情報を返します。iPlanet Application Server はこれらの情報をできるだけ透過的に処理しようとします。表 9-3 では、開始クエリでカーソル名が指定されていない場合に各データベースベンダーが返すカーソル名を示しています。


表 9-3    カーソル名

データベースのベンダー

getCursorName の戻り値

Oracle  

カーソル名が setCursorName() を使って指定されていない場合は、空の文字列を返す  

Sybase  

カーソル名が setCursorName() を使って指定されていない場合、およびリザルトセットを更新できない場合は、iPlanet Application Server によって固有のカーソル名が自動的に生成される。それ以外は、空の文字列が返される  

Informix、DB2、ODBC  

カーソル名が setCursorName() を使って指定されていない場合は、ドライバによって固有のカーソル名が自動的に生成される  


getObject
iPlanet Application Server はこの JDBC メソッドを実装し、スカラデータタイプを使った場合だけ動作します。JDBC 2.0 はマップ引数を含む補足のメソッドバージョンを追加します。iPlanet Application Server はマップを実装せず、マップ引数を無視します。


getRef、getBlob、getClob、および getArray
参照、BLOB、CLOB、およびアレイは新しい SQL-3 データタイプです。iPlanet Application Server はこれらのデータオブジェクトまたはメソッドを実装しません。しかし、getBinaryStream() および setBinaryStream() を使って、参照、BLOB、CLOB、およびアレイを操作できます。


ResultSetMetaData の操作

getTableName() メソッドは、OBDC 互換のデータベースにとって意味のある情報だけを返します。ほかのすべてのデータベースには、空の文字列を返します。


PreparedStatement の操作

PreparedStatement はデータのフェッチに繰り返し使われるクエリ、更新、または挿入ステートメントをカプセル化するクラスです。このクラスに関連する次の動作または制約事項に注意してください。



iPlanet Application Server 機能 SqlUtil.loadQuery() を使って、コンパイル済みステートメントで iASRowSet を読み込むことができます。詳細については、『Foundation Class Reference (Java)』の SqlUtil クラスの項目を参照してください。




setObject
このメソッドは、スカラデータタイプとともに使います。


addBatch
このメソッドを使うと、データ操作ステートメントのセットをまとめて、1 つのステートメントとしてデータベースに渡すことができます。addBatch() は、更新された行数または挿入された行数のカウントを返す SQL データ操作ステートメントだけ操作します。JDBC 2.0 仕様書の要求に反して、addBatch() は CREATE TABLE などの SQL データ定義ステートメントを操作しません。


setRef、setBlob、setClob、setArray
参照、BLOB、CLOB、およびアレイは新しい SQL-3 データタイプです。iPlanet Application Server は、これらのデータオブジェクト、またはデータオブジェクトを操作するメソッドを実装しません。しかし、getBinaryStream() および setBinaryStream() を使って、参照、BLOB、CLOB、およびアレイを操作できます。


getMetaData
すべてのデータベースシステムが、完全なメタデータ情報を返すとは限りません。ご使用のデータベースがどのタイプのメタデータをクライアントに提供するかを調べるには、データベースのマニュアルを参照してください。


CallableStatement の操作

CallableStatement は、ストアドプロシージャからリザルトセットを返すことをサポートするデータベースの、データベースプロシージャまたは関数呼び出しをカプセル化するクラスです。このクラスに関連する次の制約事項に注意してください。JDBC 2.0 仕様書には、呼び出し可能なステートメントは更新可能なリザルトセットを返すことができると記述されています。この機能は iPlanet Application Server ではサポートされていません。


getRef、getBlob、getClob、getArray
参照、BLOB、CLOB、およびアレイは新しい SQL-3 データタイプです。iPlanet Application Server は、これらのデータオブジェクト、またはデータオブジェクトを操作するメソッドを実装しません。しかし、getBinaryStream() および setBinaryStream() を使って、参照、BLOB、CLOB、およびアレイを操作できます。


バッチ更新の操作

JDBC 2.0 仕様書は、アプリケーションが 1 つのデータベースリクエストにある複数の SQL 更新ステートメント (INSERTUPDATEDELETE) を渡す準備をするバッチ更新機能について規定しています。ステートメントを 1 つにまとめると、大量の更新ステートメントが保留されている場合のパフォーマンスを著しく向上します。

Statement クラスには、バッチ更新を実行する 2 つの新しいメソッドがあります。

  • addBatch() を使うと、実行する前に SQL 更新ステートメント (INSERTUPDATEDELETE) をステートメントのグループに追加できます。このメソッドを使って、簡単な更新カウントを返す更新ステートメントだけを 1 つにまとめることができます。

  • executeBatch() を使うと、1 つのデータベースリクエストとして SQL 更新ステートメントのコレクションを実行できます。

バッチ更新を使うには、アプリケーションは自動コミットオプションを次のように無効にする必要があります。

...
// 自動コミットを無効にして、各ステートメントが別々にコミットすることを防ぎます。
con.setAutoCommit(false);

Statement stmt = con.createStatement();

stmt.addBatch("INSERT INTO employees VALUES(4671, 'James Williams')");
stmt.addBatch("INSERT INTO departments VALUES(560, 'Produce')");
stmt.addBatch("INSERT INTO emp_dept VALUES( 4671, 560)");

//一連のアップデートを実行するために送信します。
int[] updateCounts = stmt.executeBatch();
con.commit();

executeBatch() の前に、エラーが検出されたなどの理由でバッチオペレーションから 1 つにまとめられたすべてのステートメントを削除するには、clearBatch() を呼び出します。



JDBC 2.0 仕様書では、誤って、バッチ更新に CREATE TABLE などのデータ定義言語 (DDL) ステートメントが含まれる可能性があることを暗示しています。DDL ステートメントは簡単な更新カウントを返さず、バッチオペレーションに対してグループ化できません。また、トランザクションでデータ定義ステートメントを使用できないデータベースもあります。




分散トランザクションの作成

JDBC 2.0 仕様書は、分散トランザクションを処理する機能について規定しています。分散トランザクションは、別々のサーバマシンにある複数の異なるデータベースに適用する 1 つのトランザクションです。

分散トランザクションのサポートは、すでに iPlanet Application Server EJB コンテナに組み込まれています。EJB が TX_BEAN_MANAGED トランザクション属性を指定しない場合は、アプリケーションの分散トランザクションの自動サポートが有効になります。

Servlet および TX_BEAN_MANAGED トランザクション属性を指定する EJB でも、分散トランザクションを使用できますが、JTS の UserTransaction クラスを使ってトランザクションを管理する必要があります。次のようにします。

InitialContext ctx = null;
String dsName1 = "jdbc/SampleDS1";
String dsName2 = "jdbc/SampleDS2";
DataSource ds1 = null;
DataSource ds2 = null;

   try {
       ctx = new InitialContext();
       ds1 = (DataSource)ctx.lookup(dsName1);
       ds2 = (DataSource)ctx.lookup(dsName2);

   } catch(Exception e) {
 e.printStackTrace(System.out);
   }

UserTransaction tx = ejbContext.getUserTransaction();

tx.begin();

Connection conn1 = ds1.getConnection();
Connection conn2 = ds2.getConnection();

// いくつかの作業をここで行います。

tx.commit();

この例では、ds1 および ds2 は iPlanet Application Server を使ってグローバルデータソースとして登録する必要があります。つまり、データソースプロパティファイルには、値をインストール時に設定しなければならない ResourceMgr エントリを含める必要があります。

DataBase=ksample
DataSource=ksample
UserName=kdemo
PassWord=kdemo
DriverType=ORACLE_OCI
ResourceMgr=orarm

この例では、orarm は有効な ResourceMgr エントリである必要があり、グローバルコネクションを確実に取得できる必要があります。ResourceMgr エントリ を有効にするには、リソースマネージャは CCS0¥RESOURCEMGR にレジストリを一覧表示する必要があります。エントリ自体には次のプロパティが必要です。

DatabaseType (string key)
IsEnabled (integer type)
Openstring ( string type key)
ThreadMode ( string type key)


RowSet の操作

RowSet は、データベースやスプレッドシートなど、他の表形式データストアから取得した一連の行をカプセル化するオブジェクトです。RowSet を実装するには、プログラムが javax.sql をインポートして、RowSet インタフェースを実装する必要があります。RowSetjava.sql.ResultSet インタフェースを拡張して、JavaBean コンポーネントとしての役割を果たすことができます。

RowSet は JavaBean なので、RowSet のイベントを実装して、RowSet にプロパティを設定できます。さらに、RowSetResultSet のエクステンションなので、ResultSet を繰り返す場合と同様に、RowSet を繰り返すことができます。

RowSet を埋めるには、RowSet.execute() メソッドを呼び出します。execute() メソッドは、プロパティ値を使ってデータソースを調べてデータを取得します。設定および確認する必要があるプロパティは、起動する RowSet の実装によって異なります。

RowSet インタフェースの詳細については、『JDBC 2.0 Standard Extension API Specification』を参照してください。


iASRowSet の使用

iPlanet Application Server には、便宜上、iASRowSet という名前の RowSet クラスがあります。iASRowSetResultSet を拡張するので、呼び出しメソッドを ResultSet オブジェクトから継承します。iASRowSet は、ResultSetgetMetaData() および close() メソッドをオーバーライドします。iASRowSet は、ドライバレベルのクラスではないので、ResultSet より使いやすくなっています。

RowSet インタフェースは、表 9-4 に示すものを除いて完全にサポートされています。


表 9-4    RowSet インタフェースサポートの例外 

「Method」

引数

スローされる例外

理由

setReadOnly()  

false  

SQLException  

iASRowSet はすでに読み取り専用である  

setType()  

TYPE_SCROLL_INSENSITIVE  

SQLException  

SCROLL_INSENSITIVE はサポートされていない  

setConcurrency()  

CONCUR_UPDATABLE  

SQLException  

iASRowSet は読み取り専用である  

addRowSetListener()  

任意  

なし  

サポートされていない  

removeRowSetListener()  

任意  

なし  

サポートされていない  

setNull()  

すべてのタイプの名前  

引数は無視される  

サポートされていない  

setTypeMap()  

java.util.Map  

なし  

マップは、現在サポートされていない JDBC 2.0 の機能である  


RowSetReader
iASRowSetRowSetReader クラスを完全に実装しています。


RowSetWriter
iASRowSet は読み取り専用です。しかし、このクラスのインタフェースは将来の拡張に備えて提供されています。現在は、唯一のメソッドである writeData()SQLException をスローします。


RowSetInternal
この内部クラスは、RowSet についての情報を取得するために RowSetReader によって使われます。1 つのメソッド getOriginalRow() がありますが、1 つの行の代わりに元の ResultSet を返します。


CachedRowSet の使用法

JDBC の仕様書では、CachedRowSet と呼ばれる RowSet クラスについて規定しています。CachedRowSet を使うとデータソースからデータを取得でき、その後データの確認および変更を行う場合にデータソースから取り除きます。キャッシュした行セットは取得した元のデータ、およびアプリケーションによるデータの変更を記録します。アプリケーションが元のデータソースを更新しようとすると、行セットはデータソースに再び接続され、変更された行だけがデータベースにマージされます。


RowSet の作成

iPlanet Application Server アプリケーションに行セットを作成するには、次のコマンドを入力します。

iASRowSet rs = new iASRowSet();


JNDI を使ったデータベースドライバ

iPlanet Application Server に実装されている JDBC ドライバマネージャなどのすべての JDBC ドライバマネージャが、データベースに接続する JDBC ドライバおよび JDBC URL を調べて、そのドライバにアクセスする必要があります。ただし、JDBC URL は特定のベンダーの JDBC 実装に固有なだけでなく、特定のマシンおよびポート番号に固有な場合があります。このようなハードコードされた依存性によって、あとで異なる JDBC 実装およびマシンに簡単に移すことができる移植可能なアプリケーションの作成が難しくなります。

JDBC 2.0 には JNDI を使って、アプリケーションがネットワーク上でリモートサービスを見つけてアクセスするための、プラットフォームおよび JDBC ベンダーに依存しない同一の方法を提供することが明記されています。このハードコードされた情報の代わりに、JNDI を使うと特定のデータソースに論理名を割り当てることができます。論理名を確立すると、配置およびアプリケーションの位置を変更するには論理名を 1 回変更するだけで済みます。

JDBC 2.0 には、すべての JDBC データソースを JNDI ネーム空間の jdbc ネーミングサブコンテキストに、または子サブコンテキストの一つに登録することが明示されています。JNDI ネーム空間はファイルシステムのディレクトリ構造のように階層的であるため、簡単に参照を見つけてネストできます。データソースは、論理 JNDI 名にバインドされます。その名前は、ルートコンテキストのサブコンテキスト jdbc および論理名を識別します。データソースを変更するには、アプリケーションを変更せずに JNDI ネーム空間のエントリを変更するだけです。

JNDI の詳細については、JDBC 2.0 Standard Extension API を参照してください。

この節の残りの部分では、データソース検索の例を使って、リソースファクトリを参照する方法について説明します。以下の参照方法は、すべてのリソースに適用できます (JavaMail 参照など)。

アプリケーションコード内でリソースを検索するには、次のように行います。

String dsName = "java:comp/env/HelloDbDataSource";
DataSource ds = (javax.sql.DataSource)initContext.lookup(dsName);
Connection conn = ds.getConnection();

照会するリソースは、web.xml ファイルの res-ref-name 属性に次のように指定します。

<resource-ref>
   <description>Datasource Reference</description>
   <res-ref-name>
HelloDbDataSource</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

iPlanet 固有の配置記述子 ias-web.xmlresource-ref セクションでは、res-ref-name (アプリケーションコードでクエリの対象になる名前) をデータソースの JNDI 名に割り当てます。JNDI 名には、リソースをサーバに登録するときに、リソースファイルに定義したデータソースの名前を指定します。

<resource-ref>
   <res-ref-name>
HelloDbDataSource</res-ref-name>
   <jndi-name>
jdbc/hellodb/HelloDbDB</jndi-name>
</resource-ref>

リソース登録ファイルは XML ファイルです。データソースの JNDI 名を指定し、iPlanet サーバに登録されているドライバに割り当てます。JNDI 名は、ias-web.xml ファイルの resource-ref セクションの jndi-name 属性に指定されていなければなりません。

<ias-resource>
   <resource>
       <jndi-name>
jdbc/hellodb/HelloDbDB</jndi-name>
       <jdbc>
          <driver-type>PointBaseDriver</driver-type>
          <database-url>
              jdbc:pointbase://localhost/iassamples
          </database-url>
          <username>hellodb</username>
          <password>hellodb</password>
       </jdbc>
   </resource>
</ias-resource>

web.xmlias-web.xml、およびリソース XML ファイルの詳細については、第 11 章「配置のためのパッケージ化」を参照してください。

登録したリソースは、LDAP ネーム空間のレジストリにある次のセクションに挿入されます。

SOFTWARE¥iPlanet¥Application Server¥6.5¥DataSource

図 9-1 は、レジストリエントリを示しています。

図 9-1    データソースのレジストリエントリ




前へ     目次     索引     DocHome     次へ     
Copyright © 2002 Sun Microsystems, Inc. All rights reserved.

最新更新日 2002 年 3 月 6 日