動的照会サービスの使用

開発プロセスでは、 通常の Enterprise JavaBean (EJB) 照会サービス (デプロイメント照会 とも呼ばれる) でなく、 動的照会サービスを使用した方がいいことがあります。 例えば、テスト中に、動的照会サービスをアプリケーション・ランタイムで使用することができるため、 アプリケーションを再デプロイする必要はありません。

このタスクについて

以下は、通常の EJB 照会サービスではなく、動的照会サービスを使用する一般的な理由です。
  • デプロイメント時ではなく、アプリケーション実行時に照会をプログラムで定義する必要があります。
  • 1 つの照会から複数の CMP または CMR フィールドを戻す必要があります。 (デプロイメント照会では SELECT 文節で 1 つのエレメントしか指定できません。) 詳細については、トピック『例: EJB 照会』を参照してください。
  • 照会で計算式を戻したい。
  • 照会ステートメントで、値オブジェクト・メソッドまたは Bean メソッドを使用する。 詳細については、トピック『パス式』を参照してください。
  • 開発中に EJB 照会を対話式にテストするが、検索照会または選択照会を更新するごとに アプリケーションを繰り返しデプロイしない。

動的照会 API は、Stateless Session Bean です。他の J2EE EJB アプリケーション Bean と同じように使用できます。 この API は API パッケージの com.ibm.websphere.ejbquery に格納されています。

動的照会 Bean は、リモートおよびローカルの両方のインターフェースを持っています。 照会からリモート EJB 参照を戻す場合、または照会ステートメントにリモート・メソッドが 含まれる場合は、照会リモート・インターフェースを使用する必要があります。

リモート・インターフェース = com.ibm.websphere.ejbquery.Queryリモート・ホーム・インターフェース = com.ibm.websphere.ejbquery.QueryHome

照会からローカル EJB 参照を戻す場合、または照会ステートメントにローカル・メソッドが 含まれる場合は、照会ローカル・インターフェースを使用する必要があります。

ローカル・インターフェース = com.ibm.websphere.ejbquery.QueryLocalローカル・ホーム・インターフェース = com.ibm.websphere.ejbquery.QueryLocalHome

ローカル・インターフェースでは、 アプリケーション・サーバー・メモリーをあまり使わないため、リモート・インターフェースよりも全体的な EJB パフォーマンスが向上します。

手順

  1. そのサーバーが製品のインストール時に作成されたデフォルトのアプリケーション・サーバーとは異なる場合は、 query.ear アプリケーション・ファイルが、アプリケーションが実行されているアプリケーション・サーバーにインストールされていることを確認します。
    query.ear ファイルは、app_server_root ディレクトリーにあります。 ここで、<WAS_HOME> は WebSphere Application Server のある場所です。この製品のインストール・プログラムは、query.ear ファイルをデフォルトのアプリケーション・サーバーに、
    com/ibm/websphere/ejbquery/Query
    という JNDI 名を使用してインストールします (システム管理者は、この名前を変更できます)。
  2. 機密データへのアクセスを管理するために、リモートおよびローカルの動的照会インターフェースに executeQuery()、prepareQuery()、および executePlan() メソッド用の許可を設定します。 (このステップは、ご使用のアプリケーションにセキュリティーが要求される場合にのみ必要です。)

    どの ASN 名、CMP フィールド、または CMR フィールドが動的 EJB 照会に使用できるかは制御できないため、 ユーザーまたはシステム管理者はメソッドの使用に制限を設ける必要があります。 例えば、ユーザーが executeQuery メソッドの実行が許可されている場合、そのユーザーは任意の有効な動的照会を実行できます。 実稼働環境においては、リモート照会インターフェースのメソッドへのアクセスに制限を設けたいと考えるでしょう。

  3. アプリケーション・クライアント・コードの一部として動的照会を作成します。 サンプル・トピック『リモート・インターフェースの動的照会の例 (Remote interface dynamic query example)』、および『ローカル・インターフェースの動的照会の例 (Local interface dynamic query example)』を照会のモデルとして参照できます。これらのトピックでは、どのインポート・ステートメントを使用するかが説明されています。
  4. 照会する CMP が別のモジュールにある場合、次の処理を実行する必要があります。
    1. query.ear に対するリモート検索の実行
    2. 照会される CMP Bean がインストールされているサーバーへの query.ear ファイルのマップ
  5. クラスパスにある qryclient.jar ファイルを使用して、 クライアント・プログラムをコンパイルし、実行します。

動的照会用のリモート・インターフェースの使用。

リモート・インターフェースを使用して動的 Enterprise JavaBeans (EJB) 照会を実行する場合は、 Query インターフェースで executeQuery メソッドを呼び出します。 executeQuery メソッドにはこのインターフェース用の必須トランザクション属性があります。 このため、照会を実行するためにトランザクション・コンテキストを明示的に確立する必要がありません。

リモート・インターフェースを使用して動的 Enterprise JavaBeans (EJB) 照会を実行する場合は、 Query インターフェースで executeQuery メソッドを呼び出します。 executeQuery メソッドにはこのインターフェース用の必須トランザクション属性があります。 このため、照会を実行するためにトランザクション・コンテキストを明示的に確立する必要がありません。

以下のインポート・ステートメントで始めます。

import com.ibm.websphere.ejbquery.QueryHome;
import com.ibm.websphere.ejbquery.Query;
import com.ibm.websphere.ejbquery.QueryIterator;
import com.ibm.websphere.ejbquery.IQueryTuple;
import com.ibm.websphere.ejbquery.QueryException;

次に以下の例のように、照会ステートメントをストリングの形で書き込みます。例では低賃金従業員の名前と EJB 参照を検索しています。

String query = 
"select e.name as name , object(e) as emp from EmpBean e where e.salary < 50000"; 

QueryHome クラスから参照を取得して、Query オブジェクトを作成します。 (このクラスは executeQuery メソッドを定義します。) 簡素化するために、以下の例では Query オブジェクトに動的照会 JNDI 名を使用していることに注意してください。

InitialContext ic = new InitialContext();

Object obj =  ic.lookup("com/ibm/websphere/ejbquery/Query");

QueryHome  qh = 
 ( QueryHome) javax.rmi.PortableRemoteObject.narrow( obj, QueryHome.class );
Query qb = qh.create();

次に、照会結果セットに最大のサイズを指定する必要があります。これはクラス QueryIterator に含まれた QueryIterator オブジェクトで定義されます。 次に、照会結果セットの最大のサイズを指定する必要があります。これは、QueryIterator オブジェクトで定義されます。このクラスは、QueryIterator API パッケージに含まれています。 この例では結果セットの最大サイズを 99 に設定しています。

QueryIterator it = qb.executeQuery(query, null, null ,0, 99 );
イテレーターには IQueryTuple オブジェクトのコレクションが含まれています。これらは戻り値のコレクションのレコードです。 照会ステートメントの例の基準に対応して、このシナリオの各タプルには name の値と object(e) の値がそれぞれ 1 つ含まれています。 この照会結果の内容を表示するには、次のコードを使用します。
while (it.hasNext()) {
	IQueryTuple tuple = (IQueryTuple) it.next();
	System.out.print( it.getFieldName(1) );
	String s = (String) tuple.getObject(1);
	System.out.println( s);
	System.out.println( it.getFieldName(2) );
	Emp e = ( Emp) javax.rmi.PortableRemoteObject.narrow( tuple.getObject(2), Emp.class );
	System.out.println( e.getPrimaryKey().toString());
}
このプログラムからの出力は、次のようなものになります。
name Bob 
emp 1001
name Dave
emp 298003
...
最後に、例外をキャッチして処理します。 照会ステートメントの構文エラーまたはランタイムの処理エラーによって、例外が発生する 場合があります。 次の例ではこれらの例外をキャッチし、処理しています。
} catch (QueryException qe) {
    System.out.println("Query Exception "+ qe.getMessage() );
}

リモート・インターフェース照会での大きな結果コレクションの処理

照会で大きなコレクションの戻り値があると思われる場合、複数のより小さな、より管理しやすい量で結果を戻すようにプログラミングすることができます。 リモートの executeQuery メソッドで skipRow および maxRow パラメーターを使用して、答えを複数の塊でリトリーブします。 以下に例を示します。

int skipRow=0;
int maxRow=100;
QueryIterator it = null;
do {
		it = qb.executeQuery(query, null, null ,skipRow, maxRow );
	while (it.hasNext()) {
	// display result 
		skipRow = skipRow + maxRow;
}
} while ( ! it.isComplete() ) ;
動的照会用のローカル・インターフェースの使用。

ローカル・インターフェースを使用して動的 Enterprise JavaBeans (EJB) 照会を実行する場合は、 QueryLocal インターフェースで executeQuery メソッドを呼び出します。 このインターフェースはメソッドのトランザクションを開始しません。 このため、照会を実行するにはトランザクション・コンテキストを明示的に確立する必要があります。

注: トランザクション・コンテキストを確立するために、以下の例では begin() メソッドと commit() メソッドを呼び出しています。 これらのメソッドを使用する代わりに、単にトランザクション・コンテキスト内で実行される EJB メソッド内に照会コードを組み込むこともできます。

照会コードは以下のようなインポート・ステートメントで始めます。

import com.ibm.websphere.ejbquery.QueryLocalHome;
import com.ibm.websphere.ejbquery.QueryLocal;
import com.ibm.websphere.ejbquery.QueryLocalIterator;
import com.ibm.websphere.ejbquery.IQueryTuple;
import com.ibm.websphere.ejbquery.QueryException;

次に以下の例のように、照会ステートメントをストリングの形で書き込みます。例では低賃金従業員の名前と EJB 参照を検索しています。

String query = 
"select e.name, object(e) from EmpBean e where e.salary < 50000 ";

QueryLocalHome クラスから参照を取得して QueryLocal オブジェクトを作成します。 (このクラスは executeQuery メソッドを定義します。) 以下の例では ejb/query が動的照会の JNDI 名 (com/ibm/websphere/ejbquery/Query) を指すローカル EJB 参照として使用されていることに注意してください。

InitialContext ic = new InitialContext();
   QueryLocalHome  qh =  ( LocalQueryHome) ic.lookup( "java:comp/env/ejb/query" );
QueryLocal qb = qh.create();

コードの最後の部分はトランザクションの開始、executeQuery メソッドの呼び出し、照会結果の表示を行います。 QueryLocalIterator クラスは照会結果セットを定義するため、インスタンス化されます。 このクラスは、クラス QueryIterator API パッケージに含まれています。トランザクションの最後にはイテレーターが有効期間を喪失するため、 executeQuery 呼び出しと同じトランザクションの有効範囲でイテレーターを使用しなければならないことに注意してください。

userTransaction.begin();
QueryLocalIterator it = qb.executeQuery(query, null, null);
while (it.hasNext()) {
	IQueryTuple tuple = (IQueryTuple) it.next();
	System.out.print( it.getFieldName(1) );
	String s = (String) tuple.getObject(1);
	System.out.println( s);
	System.out.println( it.getFieldName(2) );
	EmpLocal e = ( EmpLocal ) tuple.getObject(2);
	System.out.println( e.getPrimaryKey().toString());
}
userTransaction.commit();

大抵の場合、QueryLocalIterator オブジェクトは demand-driven です。 つまり、データは増分的に戻されます。データベースからレコードを検索するごとに、イテレーターで next() メソッドが呼び出される必要があります。 (イテレーターが demand-driven でない場合もあります。 詳しくは、動的照会のパフォーマンスに関する考慮事項トピックの『ローカル QUERY インターフェース』サブセクションを参照してください。)

完全な照会結果セットはアプリケーション・サーバー・メモリーで増分的に具体化されるため、そのサイズは簡単に制御することができます。 例えば、テスト実行中に、ユーザーは照会結果のいくつかのタプルのみが戻される必要があると判断する場合もあります。 そのような場合には、QueryLocalIterator オブジェクトの close() メソッド呼び出しを使って照会ループをクローズします。 こうすることによって、イテレーターが使用する SQL リソースが解放されます。 そうしない場合、完全な結果セットがメモリーに累積されるか、トランザクションが終了するまで、これらのリソースは解放されません。


トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tque_dynamic
ファイル名:tque_dynamic.html