Oracle Containers for J2EE Enterprise JavaBeans開発者ガイド 10g(10.1.3.1.0) B31852-03 |
|
この章の内容は次のとおりです。
詳細は、次を参照してください。
次の手順では、EJB 2.1 EJB QL finderメソッドの実装方法を説明します。
finderメソッドを実装する前に、OC4Jに用意されている事前定義およびデフォルトのfinderについて検討します(「事前定義のTopLink finder」および「デフォルトのTopLink finder」を参照)。
詳細は、「finderメソッドについて」を参照してください。
事前定義またはデフォルトのfinder(「事前定義のTopLink finder」および「デフォルトのTopLink finder」を参照)のみ公開している場合は、すでに定義しています。
カスタムfinderを公開している場合は、手順2に進みます。
ejb-jar.xml
ファイルを構成します(「デプロイXMLの使用方法」を参照)。
この処理は、ここで説明するように手動で行うか、TopLink Workbenchを使用して(「TopLink Workbenchの使用方法」を参照)この手順を自動化し、高度なTopLink finder構成を利用できます。
注意
<entity>
要素の<abstract-schema-name>
サブ要素を構成します。<abstract-schema-name>
サブ要素では、EJB QL文のエンティティBeanを識別する名前を定義します。たとえば、EmpBean
という名前のエンティティBeanクラスがある場合、その<abstract-schema-name>
をEmployee
として定義すると、EJB QL文で名前Employee
を使用した場合にコンテナはその名前をEmpBean
エンティティBeanにマッピングします(例16-2を参照)。
<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-2のfindAllByEmpName
finderを参照)。
このEJBを別のEJBに関連付けるEJB QL文を定義するには、最初に適切なコンテナ管理の関連性を定義する必要があります。例16-2のfindByDeptNo
finderには、<ejb-relation-name>
Employee-Departments
との関連が必要です。詳細は、「コンテナ管理の永続性を備えたEJB 2.1エンティティBeanにおけるコンテナ管理の関連性フィールドの構成」を参照してください。
例16-1に、EmpBeanHome
というリモート・ホーム・インタフェースを示します。
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);
}
例16-2に、例16-1に示したホーム・インタフェースで宣言される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-ejb-jar.xml
ファイルをカスタムTopLink finderで構成し、ejb-jar.xml
ファイルを更新できます。
詳細は、次を参照してください。
次の手順では、EJB 2.1 EJB QL selectメソッドの実装方法を説明します。
詳細は、「selectメソッドについて」を参照してください。
public
abstract
メソッドとして定義します(「Javaの使用方法」を参照)。
ejb-jar.xml
ファイルで、次の操作を行います(「デプロイXMLの使用方法」を参照)。
<entity>
要素の<abstract-schema-name>
サブ要素を構成します。<abstract-schema-name>
サブ要素では、EJB QL文のエンティティBeanを識別する名前を定義します。たとえば、EmpBean
という名前のエンティティBeanクラスがある場合、その<abstract-schema-name>
をEmployee
として定義すると、EJB QL文で名前Employee
を使用した場合にコンテナはその名前をEmpBean
エンティティBeanにマッピングします。
<query>
要素を定義します。完全な問合せ、または条件文(WHERE
句)のみを定義できます。
selectメソッドがCollection
を返す場合、重複した項目を返さないようにするには、EJB QL文でDISTINCT
キーワードを指定します。
<query>
要素には、次の2つの主要な要素があります。
Collection
を返す場合は、返すインタフェースの型を決定します。ejb-jar.xml
ファイルの<result-type-mapping>
要素では、selectメソッドの戻り型を決定します。EJBObjects
を返すにはフラグをRemote
に設定し、EJBLocalObjects
を返すにはLocal
に設定します。
例16-3に、selectメソッドのあるコンテナ管理の永続性を備えたEJB 2.1エンティティBeanのUserAccountBean
という抽象エンティティ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);
}
...
}
例16-4に、例16-3に示した抽象エンティティBeanクラスで定義されている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-ejb-jar.xml
ファイルをカスタムTopLink ejbSelect
メソッドで構成し、ejb-jar.xml
ファイルを更新できます。
詳細は、『Oracle TopLink開発者ガイド』のファインダの作成に関する項を参照してください。
EJB 2.1では平方根、日付、時刻およびタイムスタンプ型はサポートされませんが、OC4Jでは、EJB 2.1でこれらの型をサポートするために次のような独自のEJB QL拡張を提供します。
SQRT
(v): doubleプリミティブ型とjava.lang.Double
型の両方が、引数に対してサポートされます(例16-5を参照)。
java.util.Date
(例16-6を参照)
java.sql.Date
(例16-7を参照)
java.sql.Time
(例16-8を参照)
java.sql.Timestamp
(例16-9を参照)<query> <query-method> <method-name>ejbSelectDoubleTypeSqrt</method-name> <method-params> <method-param>double</method-param> </method-params> </query-method> <result-type-mapping>Remote</result-type-mapping> <ejb-ql> SELECT OBJECT(a) FROM Dept a WHERE a.deptDoubleType = SQRT(?1) </ejb-ql> </query>例16-6 java.util.DateのEJB 2.1 EJB QL拡張の使用方法
<query> <query-method> <method-name>ejbSelectDate</method-name> <method-params> <method-param>java.util.Date</method-param> </method-params> </query-method> <result-type-mapping>Remote</result-type-mapping> <ejb-ql> SELECT OBJECT(a) FROM Dept a WHERE a.deptDate = ?1 </ejb-ql> </query>例16-7 java.sql.DateのEJB 2.1 EJB QL拡張の使用方法
<query> <query-method> <method-name>ejbSelectSqlDate</method-name> <method-params> <method-param>java.sql.Date</method-param> </method-params> </query-method> <result-type-mapping>Remote</result-type-mapping> <ejb-ql> SELECT OBJECT(a) FROM Dept a WHERE a.deptSqlDate = ?1 </ejb-ql> </query>例16-8 java.sql.TimeのEJB 2.1 EJB QL拡張の使用方法
<query> <query-method> <method-name>findByTimestamp</method-name> <method-params> <method-param>java.sql.Time</method-param> </method-params> </query-method> <result-type-mapping>Remote</result-type-mapping> <ejb-ql> SELECT OBJECT(a) FROM Dept a WHERE a.deptTime = ?1 </ejb-ql> </query>例16-9 java.sql.TimestampのEJB 2.1 EJB QL拡張の使用方法
<query> <query-method> <method-name>findByTimestamp</method-name> <method-params> <method-param>java.sql.Timestamp</method-param> </method-params> </query-method> <result-type-mapping>Remote</result-type-mapping> <ejb-ql> SELECT OBJECT(a) FROM Dept a WHERE a.deptTimestamp = ?1 </ejb-ql> </query>
|
![]() Copyright © 2002, 2008 Oracle Corporation. All Rights Reserved. |
|