エンティティBeanの問合せはfinderメソッドまたはselectメソッドを使用して表すことができます。この章では、Orion EJB 2.0でのEJB QLのfinderメソッドおよびselectメソッドの実装の詳細を説明します。
この章の内容は次のとおりです。
詳細は次のトピックを参照してください。
この項の内容は次のとおりです。
finderメソッド(ejbFind
)はエンティティBeanへの問合せを行う検索基準を定義します(詳細は「finderメソッドの理解」を参照)。
finderメソッドを定義するには次の手順を実行します。
対象のホーム・インタフェースでfind
<NAME>
メソッドを定義します。リモートまたはローカルのホーム・インタフェースで異なるfinderメソッドを指定できます。両方のホーム・インタフェースで同じfinderメソッドを定義した場合、同じエンティティBeanクラス定義にマップされます。コンテナは該当するホーム・インタフェース・タイプを返します。
finderメソッドに対する完全な問合せまたは条件文(WHERE
句)のみをデプロイメント・ディスクリプタで定義します。
EJB QL構文またはOC4J固有構文のどちらかを使用して問合せを定義できます。完全な問合せ、または問合せの条件部分(WHERE
句)のみのどちらかを指定します。
EJB QL構文はejb-jar.xml
ファイル内で定義されます。EJB QL文は各finderメソッドに対し、その<query>
要素内に作成されます。コンテナはこの文を使用して、エンティティBean参照の取得方法の条件を、関連するSQL文に変換します。
注意: EJB 2.0では、AVERAGE やSUM など、GROUP BY およびORDER BY 関数に対するEJB QLのサポートは制限されています。 |
詳細は「EJB QL構文を使用したfinderメソッドの指定」を参照してください。
OC4J固有構文はorion-ejb-jar.xml
ファイル内で定義されます。アプリケーションをデプロイするとき、OC4JはEJB QL構文をOC4J固有構文に変換します。構文は、<finder-method>
要素のquery属性で指定されます。OC4J構文を使用することで、より複雑な問合せに対してquery属性の文を変更できます。orion-ejb-jar.xml
ファイルのOC4J固有問合せ文は、ejb-jar.xml
ファイルの対応するEJB QL文よりも優先されます。
詳細は「OC4J固有構文を使用したfinderメソッドの指定」を参照してください。
注意: finderメソッドはFinderException をスローします。 |
1つのエンティティBean参照のみを取得する場合、コンテナはfind<NAME>
メソッドで返されたものと同じ型を返します。複数のエンティティBean参照をリクエストする場合、Collection
を返すようにfind<NAME>
メソッドの戻り型を定義する必要があります。重複するものが返されないようにするには、EJB QL文でDISTINCT
キーワードを指定します。一致するものが見つからない場合は空のCollection
が返されます。
EJB QL構文を使用したfinderメソッドの作成には2つのステップがあります。
finderメソッドをホーム・インタフェースに追加する必要があります。たとえば、すべての従業員を取得する場合、ホーム・インタフェース(この例ではローカル・ホーム・インタフェース)でfindAll
メソッドを定義します。
public Collection findAll() throws FinderException
1人の従業員に対するデータを取得するには、ホーム・インタフェースでfindByEmployeeNumber
メソッドを定義します。
public EmployeeLocal findByEmployeeNumber(Integer empNumber) throws FinderException;
前述の例では、返されるBeanインタフェースはローカル・インタフェースのEmployeeLocal
です。入力パラメータは従業員番号のempNumber
で、これはEJB QLの?1
パラメータで置き換えられます。
各finderメソッドはデプロイメント・ディスクリプタの<query>
要素で定義されます。findByEmployeeNumber
メソッドに対するデプロイメント・ディスクリプタの例を次に示します。
<query> <description></description> <query-method> <method-name>findByEmployeeNumber</method-name> <method-params> <method-param>java.lang.Integer</method-param> </method-params> </query-method> <ejb-ql>SELECT OBJECT(e) FROM Employee emp WHERE emp.empNumber = ?1</ejb-ql> </query>
findByEmployeeNumber
メソッドに対するEJB QL文ではEmployee
オブジェクトが選択され、ここで従業員番号はEJB QLの?1
パラメータで置き換えられます。?
という記号はメソッド・パラメータに対するプレースホルダを表します。このため、findByEmployeeNumber
メソッドでは少なくとも1つのパラメータを指定することが必要です。findByEmployeeNumber
メソッドに渡されたempNumber
は、ここで?1
の位置に置き換えられます。変数emp
は、WHERE
条件におけるEmployee
オブジェクトを識別します。
OC4J固有構文を使用したfinderメソッドの作成には2つのステップがあります。
最初にfinderメソッドをホーム・インタフェースに追加する必要があります。たとえば、Employee
エンティティBeanですべての従業員を取得するには、ホーム・インタフェース内でfindAll
メソッドを次のように定義します。
public Collection findAll() throws FinderException, RemoteException;
ホーム・インタフェースでfinderメソッドを指定した後、finderメソッドの問合せを追加してorion-ejb-jar.xml
ファイルを変更します。
<finder-method>
要素はfindByPrimaryKey
メソッド以外のすべてのfinderメソッドを定義します。定義が一番単純なfinderメソッドはfindAll
メソッドです。<finder-method>
要素のquery
属性は、完全な問合せまたは問合せのWHERE
句のみを指定できます。すべての行を取得する場合は、すべてのレコードを返す空の問合せ(query=""
)を指定します。
OC4J固有finderメソッドは、orion-ejb-jar.xml
ファイルの<finder-method>
要素で構成されます。各<finder-method>
要素では、query
属性で一部または完全なSQL文を指定します。
/*the empty WHERE clause finds all*/
<finder-method query="">
または
/*finds all records where employee equals the first input parameter*/
<finder-method query="$empName=$1">
query
属性を持つ<finder-method>
要素がある場合、ejb-jar.xml
ファイルの同じメソッドに対するEJB QLの変更よりも優先されます。
複合的なfinderメソッドを定義するには次の手順を実行します。
ejb-jar.xml
ファイルで、EJB QLを使用した単純な問合せを定義します。
アプリケーションをデプロイします。デプロイの際に、OC4JはEJB QL文をOC4J固有の対応する文に変換します。実行される完全な基礎SQL文はコメントで表示されます(例6-1「findAllメソッドのためのOC4J固有構文」を参照)。
目的の複合レベルに達するように、orion-ejb-jar.xml
ファイルで<finder-method>
要素のquery
属性を変更します。再デプロイの際に、OC4Jは新規の問合せを変換し、実行されるSQL文とともに新規のコメントを出力します。コメントをチェックして、構文が正しいことを確認します。
EJB QL構文を使用するときにorion-ejb-jar.xml
ファイルに既存の定義がある場合は、次の手順を実行します。
orion-ejb-jar.xml
ファイルで<finder-method>
要素のquery
属性を削除します。
アプリケーションを再デプロイします。OC4Jでは<finder-method>
要素のquery
属性が存在しないことが認識され、かわりにejb-jar.xml
ファイルのEJB QLのメソドロジが使用されます。
例6-1 findAllメソッドのためのOC4J固有構文
例6-1はEmployeeBean
からのすべてのレコードの取得を示しています。finderメソッド名はfindAll
です。このメソッドはすべての従業員のCollection
を返すため、パラメータが不要です。
<finder-method query="">
<!-- Generated SQL: "select EmployeeBean.empNumber,
EmployeeBean.empName, EmployeeBean.salary from EmployeeBean" -->
<method>
<ejb-name>EmployeeBean</ejb-name>
<method-name>findAll</method-name>
<method-params></method-params>
</method>
</finder-method>
注意: 問合せに詳細を追加する場合は、適切なWHERE 句でquery 属性を変更できます。この句は渡されたパラメータをドル( $ )記号を使用して参照します。たとえば1番目のパラメータは$1 、2番目のパラメータは$2 、などのように表されます。WHERE 句内で使用されるすべての<cmp-field> 要素は$<cmp-field> 名で表されます。 |
例6-2 findByNameメソッドのためのOC4J固有構文
例6-2はfindByName
メソッド(ホーム・インタフェースで定義されます)の詳細を示しています。従業員の名前はメソッド・パラメータで与えられ、$1
に置き換えられます。これはempName
というCMP名に一致します。このため、query
属性はWHERE
句に対する$empName=$1
を含むように変更されます。
<finder-method query="$empName=$1"> <method> <ejb-name>EmployeeBean</ejb-name> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </finder-method>
注意: 複数のメソッド・パラメータがある場合は、後続の<method-param> 要素で各パラメータ型を定義し、問合せ文で後続の$n (n は番号を表す)によりこれを参照します。 |
注意: SQLJOIN をquery 属性で指定できます。 |
例6-3 完全な問合せのためのOC4J固有構文
例6-3は、WHERE
句の後のセクションのみでなく、完全な問合せを指定する例を示しています。この場合は、partial
属性をfalse
に設定してから、query
属性で完全な問合せを定義する必要があります。partial
属性のデフォルト値はtrue
です(これが例6-2で指定されない理由です)。
<finder-method partial="false" query="select * from emp where $empName=$1"> <!-- Generated SQL: "select * from emp where emp.empName=?" --> <method> <ejb-name>EmployeeBean</ejb-name> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </finder-method>
注意: 生成されたSQL文を部分的なfinderメソッドの問合せに対するベースとして使用する場合は、次のことを確認してください。
|
例6-4 遅延ロードを有効にするためのOC4J固有構文
エンティティBeanのfinderメソッドでは、遅延ロードでselectメソッド(「selectメソッドの理解」を参照)が複数回起動される場合があります。デフォルトでは、遅延ロードはオフになっています。多数のオブジェクトを取得するときにその中のいくつかのみにアクセスする場合は、例6-4のように、lazy-loading
プロパティをtrue
に設定して遅延ロードをオンにします。
<finder-method partial="false" query="select * from emp where $empName=$1" lazy-loading=true> <!-- Generated SQL: "select * from emp where emp.empName=?" --> <method> <ejb-name>EmployeeBean</ejb-name> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </finder-method>
例6-5 フェッチ・サイズを設定するためのOC4J固有構文
例6-5のようにprefetch-size
属性を設定して、JDBCドライバが1回にフェッチする行数を定義できます。
<finder-method partial="false" query="select * from emp where $empName=$1" prefetch-size="15"> <!-- Generated SQL: "select * from emp where emp.empName=?" --> <method> <ejb-name>EmployeeBean</ejb-name> <method-name>findByName</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </finder-method>
Oracle JDBCドライバには、問合せ中に結果セットが移入されている間、クライアントにプリフェッチする行数を、ユーザーが設定できるようにする拡張機能が含まれています。これによって、データがフェッチされるときは複数のデータ行がフェッチされるため、データベースへのラウンドトリップが減少します(追加データはクライアントによる以後のアクセスのため、クライアント側バッファに格納されます)。プリフェッチする行数はユーザーの希望どおりに設定できます。クライアントにプリフェッチする行数のデフォルトは10です。この数字はJDBCドライバに渡されます。
selectメソッド(ejbSelect
)は、エンティティBean参照、あるいはコンテナ管理の永続性または関連フィールドの値を取得するために使用されます(「selectメソッドの理解」を参照)。
ejbSelect
メソッド定義の書式を次に示します。
public abstract type ejbSelect<METHOD>(...);
selectメソッドは、起動されるエンティティBeanインスタンスのIDをベースにはしませんが、エンティティBeanの主キーを引数として使用できます。これによって、特定のエンティティBeanインスタンスが論理的な対象となる問合せが作成されます。selectメソッドの戻り型の定義方法の詳細は、「selectメソッドに対する戻り型の定義」を参照してください。
selectメソッドを定義するには次の手順を実行します。
各selectメソッドに対するBeanクラスでejbSelect
<NAME>
メソッドを定義します。各メソッドはpublic abstract
として定義されます。このメソッドに必要なSQLは実装に含まれません。
selectメソッドに対する完全な問合せまたは条件文のみ(WHERE
句)をデプロイメント・ディスクリプタで定義します。EJB QL文は、各selectメソッドの<query>
要素に作成されます。コンテナはこの文を使用して、条件を関連するSQL文に変換します。
注意: finderメソッドの場合のように、orion-ejb-jar.xml ファイルでejbSelect メソッドに対する問合せ文を変更することはできません。 |
例6-6 Beanクラスにおけるselectメソッドの定義
例6-6は、指定した範囲内の給与を支給されているすべての従業員を取得するselectメソッドの定義を示しています。
public abstract Collection ejbSelectBySalaryRange(Float s1, Float s2) throws FinderException;
前述のselectメソッドは複数の従業員を取得するため、Collection
が返されます。給与範囲の最低値および最高値が入力パラメータで、これはEJB QLの?1
および?2
パラメータで置き換えられます。1番目の入力パラメータは?1
で返され、2番目の入力パラメータは?2
で返されます。宣言されたすべてのメソッド・パラメータの順序は、?1
、?2
〜?n
のEJB QLパラメータの順序と同じです。
例6-7 デプロイメント・ディスクリプタにおけるselectメソッド定義の指定
各selectメソッドはデプロイメント・ディスクリプタの<query>
要素で定義されます。例6-7は、例6-6のBeanクラスで定義されたejbSelectBySalaryRange
メソッドに対するデプロイメント・ディスクリプタを示しています。
<query> <description></description> <query-method> <method-name>ejbSelectBySalaryRange</method-name> <method-params> <method-param>java.lang.Float</method-param> <method-param>java.lang.Float</method-param> </method-params> </query-method> <ejb-ql>SELECT DISTINCT OBJECT(emp) From Employee emp WHERE emp.salary BETWEEN ?1 AND ?2</ejb-ql> </query>
ejbSelectBySalaryRange
メソッドにはFLOAT型の2つの入力パラメータがあります。これらの所定入力パラメータの型は<method-param>
要素で定義されます。
EJB QLは<ejb-ql>
要素で定義されます。ejbSelectBySalaryRange
メソッドは、EJB QL文内で給与の永続フィールドをemp.salary
によって評価します。emp
はEmployee
オブジェクトを表し、salary
はそのオブジェクト内の永続フィールドを表します。この2つを区切るピリオドは、エンティティBeanとその永続フィールドとの関連を示しています。
2つの入力パラメータは給与範囲の最低値および最高値を表し、それぞれ?1
および?2
の位置に置き換えられます。
ejbSelectBySalaryRange
メソッドはオブジェクトを返します。ここではDISTINCT
キーワードにより、重複レコードを返しません。
注意: selectメソッドはFinderException をスローします。 |
selectメソッドに対する戻り型を定義する際に、検討が必要な条件の一覧を次に示します。
selectメソッドによってオブジェクトが見つからない場合は、FinderException
が発生します。
selectメソッドで1つのオブジェクトを検索する場合、コンテナはejbSelect<NAME>
メソッドで返されたものと同じ型を返します。複数のオブジェクトが返された場合はFinderException
が発生します。
selectメソッドで複数のオブジェクトを検索する場合、ユーザーはejbSelect<NAME>
メソッドの戻り型をSet
またはCollection
のどちらかに定義する必要があります。Set
は重複を排除します。Collection
には重複が含まれる場合があります。たとえば、すべての顧客のすべての郵便番号を取得する場合は、Set
を使用して重複を排除します。すべての顧客の名前を取得するには、Collection
を使用してすべてのリストを取得します。一致するものが見つからない場合は空のCollection
またはSet
が返されます。