Workshop は、find および select メソッドをエンティティ Bean により簡単に追加するためのアノテーションをサポートしています。WebLogic Server に付属の EJBGen ツールでこれらのアノテーションを使用したことがあるユーザもいることでしょう。このトピックでは、find および select メソッドと EJB QL の概要について説明します。アノテーションの詳細については、「EJBGen リファレンス」を参照してください。
CMP (2.0) エンティティ Bean の find メソッドおよび select メソッドは、EJB QL を使用して定義されます。このクエリ言語は、リレーショナル データベースで使用される SQL に似ており、1 つまたは複数のエンティティ EJB またはエンティティ Bean フィールドを選択する場合に使用されます。Workshop および WebLogic Server では、EJB QL 2.0 が完全にサポートされており、EJB QL と組み合わせて使用できる数多くの追加メソッドが用意されています。
EJBGen アノテーションを使用しない場合、これらのクエリ メソッドは一般にメソッド宣言の組み合わせと Bean のデプロイメント記述子を使用して指定します。アノテーションで指定する値を通して、Workshop は記述子を更新し、Bean インタフェースに必要なメソッド宣言を生成します。
注意 :EJB QL は、EJB コンテナによって自動的に生成される findByPrimaryKey を除く、すべてのクエリ メソッドに対して使用できます。
この節のトピックは、以下のとおりです。
find メソッドは、CMP エンティティ Bean のローカルまたはリモート ホーム インタフェースで他の EJB またはクライアント アプリケーションによって呼び出され、クエリに一致するエンティティ Bean の 1 つまたは複数のインスタンスへのローカルまたはリモートの参照を返します。findByPrimaryKey などの find メソッドは、単一のエンティティ インスタンスへの参照、または java.util.Collection として返される複数のエンティティ インスタンスへの参照を返します。find メソッドは、find というプレフィックスで始まる必要があります。
Workshop では、find メソッドはクラス宣言での @Finder アノテーションを使用して指定します。@Finder アノテーションの中では複数の find メソッドをまとめて指定できます。@Finder アノテーションの属性を通して、クエリ メソッドの特徴を指定します。基本的な特徴には、使用するクエリ言語 (EJB QL または WebLogic QL)、メソッドが宣言されるインタフェース (ローカルまたはリモート ホーム)、メソッドの Java シグネチャなどがあります。
次の例では、ItemsBean_F
エンティティ Bean の中で宣言された 2 つの find メソッドを示します。どちらのメソッドも EJB QL を使用し、Bean のローカル ホーム インタフェースに追加されます。
@Finders( { @Finder(ejbQl = "SELECT OBJECT(o) from ItemsBean_F as o " + "WHERE o.itemname = ?1", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findByItemName(java.lang.String itemname)"), @Finder(ejbQl = "SELECT OBJECT(i) from ManufacturerBean_F as o, " + "IN(o.items) AS i WHERE o.usManufacturer = 1", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findByUSManufacturer()") })
注意 : @Finder アノテーションの詳細については、「EJBGen リファレンス」の「weblogic.ejbgen.Finder」を参照してください。
IDE では、[プロパティ] ビューを使用してアノテーションの値を表示および設定できます。そのためには、次の基本的な手順に従います。
@Finders アノテーションは、ソース コードに書き出されます。
@Finders アノテーションは、ソース コードに書き出されます。[プロパティ] ビューのすべての Finders 属性値はデフォルトの UNSPECIFIED 値に設定されます。
次のリストでは、find メソッドでの EJB QL クエリの一般的な使い方を示します。
ItemsBean_F
のホーム インタフェースで定義されるメソッド Collection findAll() は、データベース テーブル内のすべてのレコードを返します。
@Finder(generateOn = Finder.GenerateOn.LOCAL, ejbQl = "SELECT OBJECT(o) from ItemsBean_F as o", signature = "Collection findAll()")
EJB QL クエリは、常に EJB の抽象スキーマ名 ItemsBean_F
を使用してそれを参照します。この名前は通常、EJB の説明的な名前と同じです。これらの名前の詳細については、「weblogic.ejbgen.Entity」を参照してください。@Entity アノテーションの abstractSchemaName 属性が指定されていない場合、その ejbName 属性が使用されます。
ItemsBean_F
のホーム インタフェースで定義されるメソッド Collection findByItemName(java.lang.String itemname) は、その商品名に一致する Bean インスタンスへのすべての参照を返します。
@Finder(ejbQl = "SELECT OBJECT(o) from ItemsBean_F as o " + "WHERE o.itemname = ?1", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findByItemName(java.lang.String itemname)")
メソッド引数 itemname は、入力パラメータ ?1 に一致します。
ManufacturerBean_F
のホーム インタフェースで定義されるメソッド Collection findUSManufacturers() は、米国メーカーである ManufacturerBean_F
インスタンスへのすべての参照を返します。
@Finder(ejbQl = "SELECT OBJECT(o) from ManufacturerBean_F as o WHERE o.usManufacturer = 1", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findUSManufacturer()")
ManufacturerBean_F
および ItemsBean_F
は、各商品にはメーカーがあり、メーカーは複数の商品を生産できるというエンティティ関係を持つように定義されています。商品ごとに、ItemsBean_F
の CMR フィールド manufacturer には、メーカーへのユニークなインデックスが格納されます。ManufacturerBean_F
のホーム インタフェースで定義されるメソッド Collection findAllManufacturers() は、ItemsBean_F
に対してクエリを実行して、すべての商品の異なるメーカーを返します。同一のメーカーによって複数の商品が作成されることもあり、その場合、返される結果には同一のメーカーへの複数の参照が生じることもあります。
@Finder(ejbQl = "SELECT OBJECT(m) from ItemsBean_F as o, IN(o.manufacturer) AS m", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findAllManufacturers()")
キーワード IN は、CMR フィールドを介してオブジェクト参照を返すために使用されています。
ManufacturerBean_F
および ItemsBean_F
は、各商品にはメーカーがあり、メーカーは複数の商品を生産できるというエンティティ関係を持つように定義されています。商品ごとに、ItemsBean_F
の CMR フィールド manufacturer には、メーカーへのユニークなインデックスが格納されます。ManufacturerBean_F
のホーム インタフェースで定義されるメソッド Collection findDistinctManufacturer() は、ItemsBean_F
に対してクエリを実行して、すべての商品の異なるメーカーを返します。同一のメーカーによって複数の商品が作成されることもあり、その場合、同一のメーカーへの複数の参照が生じることもありますが、重複を返さないためにキーワード DISTINCT
が使用されています。
@Finder(ejbQl = "SELECT DISTINCT OBJECT(m) from ItemsBean_F as o, IN(o.manufacturer) AS m", generateOn = Finder.GenerateOn.LOCAL, signature = "Collection findDistinctManufacturer()")
選択メソッドは、EJB QL を使用して定義され、エンティティ Bean への (ローカルまたはリモート) 参照、または個々の CMP フィールドの値への参照を返します。select メソッドは、EJB のインタフェースで定義されません。つまり、このメソッドは、CMP エンティティ Bean クラスによって内部的に使用されるだけのプライベート メソッドです。オブジェクト参照を返す場合、select メソッドは、単一のエンティティ インスタンスへの参照、または java.util.Collection や java.util.Set として返される複数のエンティティ インスタンスへの参照を返すことができます。選択メソッドは、ejbSelect というプレフィックスで始まる必要があります。
Workshop では、select メソッドの指定は、その宣言を Bean クラスに追加し、@Select アノテーションをそのメソッドに追加することによって行います。@Finder アノテーションと同様、@Select アノテーションの属性を使用すると、クエリ メソッドの特徴 (使用する言語など) を指定できます。
次の例では、ItemsBean_S
エンティティ Bean の中で宣言された select メソッドを示します。このメソッドでは EJB QL が使用されます。
@Select(ejbQl = "SELECT OBJECT(o) from ItemsBean_S as o") public abstract java.util.Collection ejbSelectAll() throws FinderException;
注意 : @Select アノテーションの詳細については、「EJBGen リファレンス」の「weblogic.ejbgen.Select」を参照してください。
IDE では、[プロパティ] ビューを使用して @Select アノテーションの値を表示および設定できます。そのためには、前述した find メソッドの追加と同じ手順を行います (ただしカーソルはメソッド宣言に合わせます)。
次のリストでは、select メソッドでの EJB QL クエリの一般的な使い方を示します。
ItemsBean_S
クラス (そのインタフェースではない) で定義されるメソッド java.util.Collection ejbSelectAll() は、データベース テーブル内のすべてのレコードを返します。@Select(ejbQl = "SELECT OBJECT(o) from ItemsBean_S as o") public abstract java.util.Collection ejbSelectAll() throws FinderException;
ItemsBean_S
クラスで定義されるメソッド java.util.Collection ejbSelectItemNames() は、すべての商品の商品名のみを返します。
@Select(ejbQl = "SELECT o.itemname from ItemsBean_S as o") public abstract java.util.Collection ejbSelectItemNames() throws FinderException;
オブジェクト参照を返すクエリと同じように、CMP フィールドを返すクエリにも入力パラメータ、リテラル値、IN キーワードを使用した関係のクエリ、および重複レコードを避けるための DISTINCT キーワードを含めることができます。ItemsBean_S
クラスで定義されるメソッド java.util.Collection ejbSelectByItemName(java.lang.String itemname) は、引数 itemname に一致する商品の商品名のみを返します。
@Select(ejbQl = "SELECT o.itemname from ItemsBean_S as o WHERE o.itemname = ?1") public abstract java.util.Collection ejbSelectNameByItemName(String itemname) throws FinderException;
EJB QL 2.0 では、数多くの標準演算子が定義されています。IN
、DISTINCT
のような演算子の一部と、EJB の CMP フィールドへのアクセスなどに使用するナビゲーション演算子としての「.」の使用については、前述の節で説明済みです。その他の演算子には以下のものがあります。
<
、>
、<=
、>=
、=
、および <>
。NOT
、AND
、および OR
。int
、double
、または float
) の絶対値を返す ABS(
number)
、および平方根を返す SQRT(
double)
。String
フィールドを持つパターン マッチング用に使用されます。任意の文字数のマッチングの場合は「%」を使用し、正確に 1 つの文字のマッチングの場合は「_」を使用します (これらの文字がパターン内に実際にある場合は「\」を使用します)。たとえば次のクエリは、価格が「.95」で終わるすべての商品を選択します。
SELECT OBJECT(o) from ItemsBean_S as o WHERE o.price LIKE '%.95'
String
関数。CONCAT(
String1, String2)
、LENGTH(
String)
、LOCATE(
StringToFind, ContainingString [, starting position])
(java.lang.String.indexOf と同じ)、および SUBSTRING(
String, startposition, endposition)
。
BETWEEN
。値の範囲 (その値を含む) を指定します。たとえば次のクエリは、$20 から $40 のすべての商品を返します。
SELECT OBJECT(o) from ItemsBean as o WHERE o.price BETWEEN 20.00 AND 40.00
IS NULL
。null フィールドかどうかをテストするために使用されます。String などのオブジェクトを保持する CMP フィールド、および単一のオブジェクトを保持する CMR フィールドは null になる場合があります。一方、プリミティブ値を保持する CMP フィールド、およびオブジェクトの集合を保持する CMR フィールドは null にはなりません。たとえば次のクエリは、メーカーが不明なすべての商品を返します (エンティティの関係は先述の節で説明したものと同じという前提です)。
SELECT OBJECT(o) from ItemsBean as o WHERE o.manufacturer IS NULL
IS EMPTY
。空のセットかどうかをテストするために使用されます (特にオブジェクトの集合を保持する特定の CMR フィールド)。たとえば次のクエリは、データベース内に既知の商品がないすべてのメーカーを返します。
SELECT OBJECT(o) from ManufacturerBean as o WHERE o.items IS EMPTY
MEMBER OF
。オブジェクトが集合ベースの関係の一部であるかどうかを評価するために使用されます。たとえば次のクエリは、所定の商品のメーカーを返します。
SELECT OBJECT(o) from ManufacturerBean as o, IN (o.items) AS allItems, ItemsBean oneItem WHERE oneItem.itemname = ?1 AND oneItem MEMBER OF allItems
EJB QL クエリと、この言語で定義されている演算子の詳細については、ファインダ メソッドのサンプルと選択メソッドのサンプル、またはお好きな J2EE ドキュメントを参照してください。