ヘッダーをスキップ

Oracle Containers for J2EE Enterprise JavaBeans開発者ガイド
10g(10.1.3.1.0)

B31852-03
目次
目次
索引
索引

戻る 次へ

16 EJB 2.1問合せの実装

この章の内容は次のとおりです。

詳細は、次を参照してください。

EJB 2.1 EJB QL finderメソッドの実装

次の手順では、EJB 2.1 EJB QL finderメソッドの実装方法を説明します。

finderメソッドを実装する前に、OC4Jに用意されている事前定義およびデフォルトのfinderについて検討します(「事前定義のTopLink finder」および「デフォルトのTopLink finder」を参照)。

詳細は、「finderメソッドについて」を参照してください。

  1. finderメソッドをホーム・インタフェースに定義します(「Javaの使用方法」を参照)。

    事前定義またはデフォルトのfinder(「事前定義のTopLink finder」および「デフォルトのTopLink finder」を参照)のみ公開している場合は、すでに定義しています。

    カスタムfinderを公開している場合は、手順2に進みます。

  2. ejb-jar.xmlファイルを構成します(「デプロイXMLの使用方法」を参照)。


    注意

    この処理は、ここで説明するように手動で行うか、TopLink Workbenchを使用して(「TopLink Workbenchの使用方法」を参照)この手順を自動化し、高度なTopLink finder構成を利用できます。 


    1. EJB QL問合せで参照することを計画している各エンティティBeanについて、<entity>要素の<abstract-schema-name>サブ要素を構成します。

      <abstract-schema-name>サブ要素では、EJB QL文のエンティティBeanを識別する名前を定義します。たとえば、EmpBeanという名前のエンティティBeanクラスがある場合、その<abstract-schema-name>Employeeとして定義すると、EJB QL文で名前Employeeを使用した場合にコンテナはその名前をEmpBeanエンティティBeanにマッピングします(例16-2を参照)。

    2. EJBホーム・インタフェースで公開した各finderメソッドの<query>要素を定義します。

      <query>要素には次のサブ要素があります。

      • <description>: オプションの説明テキスト。

      • <query-method>: finderメソッドを記述し、次のサブ要素を含みます。

        <method-name>: finderメソッドを識別します。この要素は、ホーム・インタフェースで定義したメソッド名と同じ名前で構成します。

        <method-params>: finderが引数を受け取る場合は、この要素を定義し、各引数について、引数型を与える<method-param>サブ要素を定義します。引数の型と順序は、このfinderのシグネチャで指定されている型および順序と一致している必要があります。

      • <ejb-ql>: このメソッドのEJB QL文が含まれます。

        完全な問合せ、または条件文(WHERE句)のみを定義できます。

        finderメソッドがCollectionを返す場合、重複した項目を返さないようにするには、EJB QL文でDISTINCTキーワードを指定します。

        EJB QLでパラメータ(<method-params>で指定)を使用するには、<integer>?表記を使用します。<integer>1から開始します。たとえば、?1は最初の<method-param>要素に対応し、?2は2番目の<method-param>要素に対応します。以下も同様です(例16-2findAllByEmpName finderを参照)。

        このEJBを別のEJBに関連付けるEJB QL文を定義するには、最初に適切なコンテナ管理の関連性を定義する必要があります。例16-2findByDeptNo finderには、<ejb-relation-name> Employee-Departmentsとの関連が必要です。詳細は、「コンテナ管理の永続性を備えたEJB 2.1エンティティBeanにおけるコンテナ管理の関連性フィールドの構成」を参照してください。

Javaの使用方法

例16-1に、EmpBeanHomeというリモート・ホーム・インタフェースを示します。

例16-1    コンテナ管理の永続性を備えたEJB 2.1エンティティBeanのリモート・ホーム・インタフェースのfinderメソッド

package cmpapp;

import javax.ejb.*;
import java.rmi.*;

public interface EmpBeanHome extends EJBHome {
    public EmpBean create(Integer empNo, String empName) throws CreateException;

    /**
     * Finder methods. These are implemented by the container. You can
     * customize the functionality of these methods in the deployment
     * descriptor through EJB-QL.
     **/

// Predefined Finders: <query> element in ejb-jar.xml not required

    public Topic findByPrimaryKey(Integer key) throws FinderException;
    public Collection findManyBySQL(String sql, Vector args) throws FinderException

// Default Finder: <query> element in ejb-jar.xml not required

    public Topic findByEmpNo(Integer empNo) throws FinderException;

// Custom Finders: <query> element is required in ejb-jar.xml

    public Collection findAllRegionalEmployees(Integer empNo) throws FinderException;
    public Collection findAllByEmpName(String empName) throws FinderException;
    public Topic findByDeptNo(Integer deptNo) thorws FinderException
    public Collection findAllBetweenSalaries(Integer lowSalary, Integer highSalary);

}

デプロイXMLの使用方法

例16-2に、例16-1に示したホーム・インタフェースで宣言されるfinderのejb-jar.xmlを示します。

例16-2    EJB 2.1 EJB QL finderのejb-jar.xml

<enterprise-beans>
    <entity>
        <display-name>EmpBean</display-name>
        <ejb-name>EmpBean</ejb-name>
        ...
        <abstract-schema-name>Employee</abstract-schema-name>
        <cmp-field><field-name>empNo</field-name></cmp-field>
        <cmp-field><field-name>empName</field-name></cmp-field>
        <cmp-field><field-name>salary</field-name></cmp-field>
        <primkey-field>empNo</primkey-field>
        <prim-key-class>java.lang.Integer</prim-key-class>
        ...
        <query>
            <description>Regional employees have empNo greater than 10000</description>
            <query-method>
                    <method-name>findAllRegionalEmployees</method-name>
                    <method-params></method-params>
            </query-method>
            <ejb-ql>SELECT OBJECT(e) FROM Employee e WHERE e.empNo > 10000</ejb-ql>
        </query>
        <query>
            <description>Find all employees with the given name</description>
            <query-method>
                <method-name>findAllByEmpName</method-name>
                <method-params>
                    <method-param>java.lang.String</method-param>
                </method-params>
            </query-method>
            <ejb-ql>SELECT OBJECT(e) FROM Employee e WHERE e.empName = ?1</ejb-ql>
        </query>
        <query>
            <description>Relationship finder</description>
            <query-method>
                <method-name>findByDeptNo</method-name>
                <method-params>
                    <method-param>java.lang.Integer</method-param>
                </method-params>
            </query-method>
            <ejb-ql>
              SELECT DISTINCT OBJECT(e) From Employee e, IN (e.dept) AS d WHERE d.deptNo = ?1
           </ejb-ql>
        </query>
        <query>
            <description>Find all employees with salaries in the given range</description>
            <query-method>
                <method-name>findAllBetweenSalaries</method-name>
                <method-params>
                    <method-param>java.lang.Integer</method-param>
                    <method-param>java.lang.Integer</method-param>
                </method-params>
            </query-method>
            <ejb-ql>
                SELECT OBJECT (e) FROM Employee e WHERE e.salary BETWEEN ?1 and ?2
            </ejb-ql>
        </query>
    ...
    </entity>
...
</enterprise-beans>
<relationships>
    <ejb-relation>
        <ejb-relation-name>Employee-Departments</ejb-relation-name>
        <ejb-relationship-role>
            <ejb-relationship-role-name>Employee-has-Departments</ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
            <relationship-role-source>
                <ejb-name>Department</ejb-name>
            </relationship-role-source>
            <cmr-field>
                <cmr-field-name>dept</cmr-field-name>
                <cmr-field-type>java.lang.Integer</cmr-field-type>
            </cmr-field>
        </ejb-relationship-role>
    <ejb-relation>
...
<relationships>

TopLink Workbenchの使用方法

TopLink Workbenchを使用して、toplink-ejb-jar.xmlファイルをカスタムTopLink finderで構成し、ejb-jar.xmlファイルを更新できます。

詳細は、次を参照してください。

EJB 2.1 EJB QL selectメソッドの実装

次の手順では、EJB 2.1 EJB QL selectメソッドの実装方法を説明します。

詳細は、「selectメソッドについて」を参照してください。

  1. selectメソッドを抽象エンティティBeanクラスのpublic abstractメソッドとして定義します(「Javaの使用方法」を参照)。

  2. ejb-jar.xmlファイルで、次の操作を行います(「デプロイXMLの使用方法」を参照)。

    1. EJB QL問合せで参照することを計画している各エンティティBeanについて、<entity>要素の<abstract-schema-name>サブ要素を構成します。

      <abstract-schema-name>サブ要素では、EJB QL文のエンティティBeanを識別する名前を定義します。たとえば、EmpBeanという名前のエンティティBeanクラスがある場合、その<abstract-schema-name>Employeeとして定義すると、EJB QL文で名前Employeeを使用した場合にコンテナはその名前をEmpBeanエンティティBeanにマッピングします。

    2. EJBホーム・インタフェースで公開する各selectメソッドの<query>要素を定義します。

      完全な問合せ、または条件文(WHERE句)のみを定義できます。

      selectメソッドがCollectionを返す場合、重複した項目を返さないようにするには、EJB QL文でDISTINCTキーワードを指定します。

      <query>要素には、次の2つの主要な要素があります。

      • <method-name>要素はselectメソッドを識別します。この要素は、Beanクラスで定義した名前と同じ名前で構成します。

      • <ejb-ql>要素には、このメソッドのEJB QL文が含まれます。

    3. 問合せがCMR値のCollectionを返す場合は、返すインタフェースの型を決定します。

      ejb-jar.xmlファイルの<result-type-mapping>要素では、selectメソッドの戻り型を決定します。EJBObjectsを返すにはフラグをRemoteに設定し、EJBLocalObjectsを返すにはLocalに設定します。

Javaの使用方法

例16-3に、selectメソッドのあるコンテナ管理の永続性を備えたEJB 2.1エンティティBeanのUserAccountBeanという抽象エンティティBeanクラスを示します。

例16-3    selectメソッドのあるコンテナ管理の永続性を備えたEJB 2.1エンティティBeanの実装

package oracle.otnsamples.ejbql;

import javax.ejb.*;
import java.util.*;

public abstract class UserAccountBean implements EntityBean {

    // Non-Persistent State

    protected EntityContext ctx;

    /**
     * Begin abstract get/set methods. Container-managed
     * persistent fields are specified in the ejb-jar.xml
     * deployment descriptor.
     */

    public abstract Long getAccountnumber();
    public abstract void setAccountnumber(Long newAccountnumber);

    public abstract Long getCreditlimit();
    public abstract void setCreditlimit(Long newCreditlimit);

    /**
     * Select methods. These are implemented by the container. You can
     * customize the functionality of these methods in the deployment
     * descriptor through EJB-QL.
     *
     * These methods are NOT exposed in the bean's home interface.
     */

    public abstract Long ejbSelectCreditLimit(Long accountnumber) throws FinderException;
    public abstract Collection ejbSelectByTopAccounts() throws FinderException;

    /**
     * Begin buisness logic methods that use select methods.
     *
     * These methods are exposed in the bean's home interfaces.
     */

    /**
     * Method to perform post-processing operations on all the
     * UserAccounts retrieved by calling ejbSelectByTopAccounts. This
     * method further process the retrieved UserAccounts and checks
     * for the Accounts with TopCredits (credit limits) and returns the
     * collection of input number of UserAccounts.
     * Post-processing information within the EJB container itself
     * has the following two advantages:
     *     1) It improves performance as the application can now leverage
     *            the advantage of the vast resources available to the server.
     *     2) The data-processing code should go into the business logic
     *            and not the Web-tier. This helps in maintaining the code.
     * Consider these advantages when deciding between ejbFind and
     * ejbSelect methods.
     *
     * @return Collection of <input number of> Top (credited) UserAccounts
     */
    public Collection ejbHomeTopAccounts(String accountNumbers) throws FinderException {
        // Invoke the ejbSelect method and get all the Account Information.
        Collection collection = this.ejbSelectByTopAccounts();
        ...
        return topAccounts;
    }

    /**
     * Method to call ejbSelectCreditLimit and return the credit limit value
     * for the input accountnumber without post-processing.
     * Please note that this method returns a Long instead of a collection
     * that is returned normally by the EJB container. This is a major
     * advantage of ejbSelect methods. Using these methods, You can return
     * an object from 'within' the CMP instead of 'the' CMP. This way, the
     * application uses the server and the EJB container resources more
     * effeciently.
     *
     * @return Credit Limit of the input UserAccount
     */
    public Long ejbHomeCreditLimit(Long accountnumber) throws FinderException {
        // Return the Credit Limit of the specified Account
        return this.ejbSelectCreditLimit(accountnumber);
    }
    ...
}

デプロイXMLの使用方法

例16-4に、例16-3に示した抽象エンティティBeanクラスで定義されているselectメソッドのejb-jar.xmlファイルを示します。

例16-4    EJB 2.1 EJB QL selectメソッドのejb-jar.xml

  <enterprise-beans>
    <entity>
      <description>Entity Bean ( CMP )</description>
      <display-name>UserAccount</display-name>
      <ejb-name>UserAccount</ejb-name>
      <local-home>oracle.otnsamples.ejbql.UserAccountLocalHome</local-home>
      <local>oracle.otnsamples.ejbql.UserAccount</local>
      <ejb-class>oracle.otnsamples.ejbql.UserAccountBean</ejb-class>
      <persistence-type>Container</persistence-type>
      <prim-key-class>java.lang.Long</prim-key-class>
      <abstract-schema-name>UserAccount</abstract-schema-name>
      <cmp-field>
        <field-name>accountnumber</field-name>
      </cmp-field>
      <cmp-field>
        <field-name>creditlimit</field-name>
      </cmp-field>
      <primkey-field>accountnumber</primkey-field>
      <query>
        <description>Selects all accounts and post-process to find top accounts</description>
        <query-method>
          <method-name>ejbSelectByTopAccounts</method-name>
        </query-method>
        <ejb-ql>select distinct object(ua) from UserAccount ua</ejb-ql>
      </query>
      <query>
        <description>Retrieves the Credit Limit for an Account</description>
        <query-method>
          <method-name>ejbSelectCreditLimit</method-name>
          <method-params>
            <method-param>java.lang.Long</method-param>
          </method-params>
        </query-method>
        <ejb-ql>
            select ua.creditlimit from UserAccount ua where ua.accountnumber = ?1
        </ejb-ql>
      </query>
    </entity>
  </enterprise-beans>

TopLink Workbenchの使用方法

TopLink Workbenchを使用して、toplink-ejb-jar.xmlファイルをカスタムTopLink ejbSelectメソッドで構成し、ejb-jar.xmlファイルを更新できます。

詳細は、『Oracle TopLink開発者ガイド』のファインダの作成に関する項を参照してください。

OC4J EJB 2.1 EJB QL拡張

EJB 2.1では平方根、日付、時刻およびタイムスタンプ型はサポートされませんが、OC4Jでは、EJB 2.1でこれらの型をサポートするために次のような独自のEJB QL拡張を提供します。


戻る 次へ
Oracle
Copyright © 2002, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引