WebLogic エンタープライズ JavaBeans (EJB) プログラマーズ ガイド
![]() |
![]() |
![]() |
![]() |
EJB クエリ言語 (QL) は、コンテナ管理による永続性を利用する 2.0 エンティティ EJB のファインダ メソッドを定義する移植可能なクエリ言語です。このクエリ言語は SQL に似ており、クエリ内の 1 つまたは複数のエンティティ EJB オブジェクトまたはフィールドを選択する場合に使用します。findByPrimaryKey()
以外のすべてのファインダ メソッドのクエリをデプロイメント記述子で作成できます。findByPrimaryKey
は、EJB コンテナで自動的に処理されます。
デプロイメント記述子では、EJB QL クエリ文字列を使用して、EJB 2.0 のエンティティ Bean の各ファインダ クエリを定義する必要があります。WebLogic Query Language (WLQL) を EJB 2.0 エンティティ Bean で使用することはできません。WLQL は、EJB 1.1 のコンテナ管理による永続性で使用することを想定しています。WLQL および EJB 1.1 のコンテナ管理による永続性の詳細については、「EJB 1.1 CMP 用の WebLogic クエリ言語 (WLQL) の使用」を参照してください。
WebLogic Server には、標準の EJB QL の拡張であり、SQL に似た WebLogic QL という言語が用意されています。この言語はファインダ式と連携し、RDBMS の EJB オブジェクトのクエリ用に使用されます。query
は、weblogic-ql
要素を使用して、weblogic-cmp-jar.xml
デプロイメント記述子に定義します。
ejb-jar
ファイルには、weblogic-cmp-jar.xml
ファイルの weblogic-ql
要素に対応するクエリ要素が必要です。ただし、weblogic-cmp-jar.xml
のクエリ要素の値は、ejb-jar.xml
のクエリ要素の値をオーバーライドします。
以下のトピックは、EJB 2.0 QL の WebLogic QL 拡張機能を使用する際のガイドラインを示します。
EJB WebLogic QL upper
および lower
拡張機能は、大文字と小文字の違いがある以外は検索式の文字と一致する結果をファインダ メソッドが返せるように、引数の大文字と小文字を変換します。大文字と小文字の変換は文字列を照合するための一時的なものなので、データベース内に永続しません。基底のデータベースも、upper
および lower
関数をサポートしている必要があります。
upper
関数は、文字列の照合の前に、引数内の文字をすべて大文字に変換します。クエリ内で大文字で表された式で upper
関数を使用すると、大文字であるか小文字であるかに関係なく、式に一致するすべての項目が返されます。次に例を示します。
select name from products where upper(name)='DETERGENT';
lower
関数は、文字列の照合の前に、引数内の文字をすべて小文字に変換します。クエリ内で小文字で表された式で lower
関数を使用すると、大文字であるか小文字であるかに関係なく、式に一致するすべての項目が返されます。
select type from products where lower(name)='domestic';
WebLogic クエリ言語 (WL QL) の拡張機能である ORDERBY
は、Finder
メソッドと連携して、選択における CMP フィールドの選択順序を指定するキーワードです。
コード リスト 8-13 id による順序付けを指定する ORDERBY 拡張機能
ORDERBY
SELECT OBJECT(A) from A for Account.Bean
ORDERBY A.id
次のように ORDERBY
に昇順 [ASC
] か降順 [DESC
] か指定することもできます。
コード リスト 8-14 id による順序付けを指定する ORDERBY 拡張機能 (昇順/降順指定)
ORDERBY <field> [ASC|DESC], <field> [ASC|DESC]
SELECT OBJECT(A) from A for Account.Bean, OBJECT(B) from B for Account.Bean
ORDERBY A.id ASC; B.salary DESC
注意 : ORDERBY
は、すべてのソート処理を DBMS に委ねます。このため、取得される結果の順序は、実行中の Bean の基盤となる特定の DBMS によって異なります。
WebLogic Server では、EJB QL のサブクエリの次のような機能をサポートしています。
WebLogic QL とサブクエリの関係は、SQL クエリとサブクエリの関係に似ています。WebLogic QL のサブクエリは、外部 WebLogic QL クエリの WHERE
句内で使用してください。若干の例外はありますが、サブクエリの構文は WebLogic QL クエリのものとほぼ同じです。
WebLogic QL を指定する手順については、「EJB QL の EJB 2.0 WebLogic QL 拡張機能の使い方」を参照してください。この手順に従って、SELECT
文で次の例のようにサブクエリを指定します。
次のクエリは、成績順位をもとに平均以上の生徒を選択しています。
SELECT OBJECT(s) FROM studentBean AS s WHERE s.grade > (SELECT AVG(s2.grade) FROM StudentBean AS s2)
上記クエリの例の中で、サブクエリ、「SELECT AVG(s2.grade) FROM StudentBean AS s2」が EJB QL クエリと同じ構文を備えている点に注意してください。
サブクエリをネストすることもできます。この深さは、基盤データベースのネストの許容範囲によって制限されます。
WebLogic QL クエリでは、メイン クエリとそのすべてのサブクエリの FROM
句で宣言される識別子がユニークでなければなりません。これはつまり、サブクエリの内側で前にローカルに宣言した識別子をそのサブクエリで再び宣言することはできないということです。
たとえば、次の例は無効です。Employee Bean がクエリとサブクエリの双方で emp として宣言されています。
SELECT OBJECT(emp)
FROM EmployeeBean As emp
WHERE emp.salary=(SELECT MAX(emp.salary) FROM
EmployeeBean AS emp WHERE employee.state=MA)
SELECT OBJECT(emp)
FROM EmployeeBean As emp
WHERE emp.salary=(SELECT MAX(emp2.salary) FROM
EmployeeBean AS emp2 WHERE emp2.state=MA)
この例では、サブクエリの Employee Bean がメインクエリの Employee Bean と異なる識別子になるように正しく宣言されています。
WebLogic QL サブクエリの戻り値の型は、次のような各種の型のいずれかになります。
WebLogic Server は、cmp-field
で構成されている戻り値型をサポートしています。サブクエリから返される結果は、1 つの値または値の集合から構成されている可能性があります。cmp-field
型の値を返すサブクエリの例を次に示します。
SELECT emp.salary FROM EmployeeBean AS emp WHERE emp.dept = `finance'
このサブクエリは、財務部門の従業員の給料すべてを選択しています。
WebLogic Server は、ある cmp-field
に対する集約から構成されている戻り値型をサポートしています。集約は必ず 1 つの値から構成されるので、ここで返される値も常に 1 つの値になります。cmp-field
の集約 (MAX
) の型の値を返すサブクエリの例を次に示します。
SELECT MAX(emp.salary) FROM EmployeeBean AS emp WHERE emp.state=MA
このサブクエリは、マサチューセッツで最高額の給料を 1 つだけ選択しています。
集約関数の詳細については、「集約関数の使用」を参照してください。
WebLogic Server は、単純主キーを持つ 1 つの cmp-bean
で構成されている戻り値型をサポートしています。
単純主キーを持つ Bean 型の値を返すサブクエリの例を次に示します。
SELECT OBJECT(emp) FROM EMployeeBean As emp WHERE emp.department.budget>1,000,000
このサブクエリは、$1,000,000 以上の予算がある部門の全従業員のリストを返します。
注意 : 複合主キーを持つ Bean はサポートされていません。複合主キーを持つ Bean をサブクエリの戻り値の型として指定しようとしても、クエリをコンパイルする時点で失敗に終わります。
サブクエリを比較演算子および算術演算子のオペランドとして使用します。WebLogic QL では、以下の演算子のオペランドとしてサブクエリをサポートしています。
[NOT]IN
比較演算子は、左側のオペランドが右側のサブクエリ オペランドのメンバーかどうか検査します。
サブクエリが NOT IN
オペレータの右側のオペランドとなっている例を次に示します。
SELECT OBJECT(item)
FROM ItemBean AS item
WHERE item.itemId NOT IN
(SELECT oItem2.item.itemID
FROM OrderBean AS orders2, IN(orders2.orderItems)oIttem2
メイン クエリの NOT IN
演算子では、サブクエリによって返された集合の中に含まれていない品目すべてを選択しています。したがって、最終的に、メインクエリが未注文の品目すべてを選択します。
[NOT]EXISTS
比較演算子は、サブクエリ オペランドによって返された集合が空かどうか検査します。
サブクエリが NOT EXISTS
オペランドのオペランドとなっている例を次に示します。
SELECT (cust) FROM CustomerBean AS cust
WHERE NOT EXISTS
(SELECT order.cust_num FROM OrderBean AS order
WHERE cust.num=order_num)
これは、相関サブクエリを用いたクエリの一例となっています。 詳細については「相関サブクエリと非相関サブクエリ」を参照してください。次のクエリは、注文していない顧客をすべて返します。
SELECT (cust) FROM CustomerBean AS cust
WHERE cust.num NOT IN
(SELECT order.cust_um FROM OrderBean AS order
WHERE cust.num=order_num)
右側のサブクエリ オペランドが 1 つの値を返す場合、比較の算術演算子を使用できます。右側のサブクエリが複数の値を返す場合には、サブクエリの前に ANY
または ALL
修飾子が必要です。
SELECT OBJECT (order)
FROM OrderBean AS order, IN(order.orderItems)oItem
WHERE oItem.quantityOrdered =
(SELECT MAX (subOItem.quantityOrdered)
FROM Order ItemBean AS subOItem
WHERE subOItem,item itemID = ?1)
AND oItem.item.itemId = ?1
特定の品目 ID に対し、サブクエリはその品目の注文の最高数を返します。サブクエリが返している集合が、「=」演算子に必要な 1 つの値となっている点に注意してください。
メイン クエリの「=
」演算子では、これと同じ品目 ID に対し、どの注文の注文品目の注文量がサブクエリから返された注文の最高数に等しいかを調べています。最終的に、特定の品目について注文が最高数である OrderBean をクエリが返します。
右側のサブクエリ オペラントが複数の値を返す場合には、算術演算子と ANY
または ALL
と組み合わせて使用します。
ANY
または ALL
を使用したサブクエリの例を次に示します。
SELECT OBJECT (order)
FROM OrderBean AS order, IN(order.orderItems)oItem
WHERE oItem.quantityOrdered > ALL
(SELECT subOItem.quantityOrdered
FROM OrderBean AS suborder IN (subOrder.orderItems)subOItem
WHERE subOrder,orderId = ?1)
サブクエリは、特定の注文 ID に対し、その注文 ID で注文された各品目の注文数の集合を返します。メイン クエリの「>」
ALL
演算子は、各品目の注文数がサブクエリから返された集合内のすべての値を上回っている注文すべてを探しています。最終的にメインクエリは、入力された注文に対して、全品目で注文数を上回っている注文すべてを返します。
サブクエリが複数の値を持つ結果を返す可能性があるため、「>」
演算子ではなく、「>」ALL
演算子が使用されている点に注意してください。
WebLogic Server は、相関サブクエリと非相関サブクエリの双方をサポートしています。
非相関サブクエリは、その外部クエリとは独立に評価されます。非相関サブクエリの例を次に示します。
SELECT OBJECT(emp) FROM EmployeeBean AS emp
WHERE emp.salary>
(SELECT AVG(emp2.salary) FROM EmployeeBean AS emp2)
この非相関サブクエリの例では、平均以上の給与の従業員を選択しています。この例では、算術演算子「>」を使用します。
相関サブクエリは、その外部クエリの値がサブクエリでの評価に関与するサブクエリです。相関サブクエリの例を次に示します。
SELECT OBJECT (mainOrder) FROM OrderBean AS mainOrder
WHERE 10>
(SELECT COUNT (DISTINCT subOrder.ship_date)
FROM OrderBean AS subOrder
WHERE subOrder.ship_date>mainOrder.ship_date
AND mainOrder.ship_date IS NOT NULL
この相関サブクエリの例では、最後に出荷された 10 個の注文を選択しています。NOT IN
演算子を使用しています。
注意 : 相関クエリでは、非相関クエリより処理オーバーヘッドが大きくなる可能性があることに注意してください。
サブクエリ内で DISTINCT
句を使用すると、そのサブクエリで生成される SELECT DISTINCT
内で SQL SELECT DISTINCT を使うことができます。サブクエリでの DISTINCT
句の使い方は、メインクエリでの使い方とは異なります。メインクエリ内の DISTINCT
句は EJB コンテナによって施されますが、サブクエリ内の DISTINCT
句は生成された SQL の SQL SELECT DISTINCT
によって施されます。サブクエリの DISTINCT
句の例を示します。
SELECT OBJECT (mainOrder) FROM OrderBean AS mainOrder
WHERE 10>
(SELECT COUNT (DISTINCT subOrder.ship_date)
FROM OrderBean AS subOrder
WHERE subOrder.ship_date>mainOrder.ship_date
AND mainOrder.ship_date IS NOT NULL
WebLogic Server では、WebLogic QL の集約関数をサポートしています。これらは、WHERE
句のようなクエリの一部ではなく、SELECT
句の対象として使われるのみです。集約関数の振る舞いは SQL 関数と似ています。これらの関数は、クエリの WHERE
条件によって返される Bean の外側で評価されます。
WebLogic QL を指定する手順については、「EJB QL の EJB 2.0 WebLogic QL 拡張機能の使い方」を参照してください。これに従って、次の表のサンプルのように、集約関数を指定した SELECT 文を記述します。
次の手順で、ResultSet として集約関数を返すことができます。
WebLogic Server は、複数カラム クエリの結果を java.sql.ResultSet
の形式で返す、ejbSelect()
クエリをサポートしています。この機能を支援するために、WebLogic Server では、次のように SELECT 句の対象フィールドをカンマで区切って指定できるようになりました。
SELECT emmp.name, emp.zip FROM EmployeeBean AS emp
このクエリは、従業員の名前と郵便番号の値をカラムとしその数行を含んだ java.sqlResultSet
を返します。
WebLogic QL を指定する手順については、「EJB QL の EJB 2.0 WebLogic QL 拡張機能の使い方」を参照してください。「EJB QL の EJB 2.0 WebLogic QL 拡張機能の使い方」の手順に従って、上記のクエリの例で WebLogic QL を指定したように、ResultSet を指定するクエリを記述します。また、同様にこれに従って、下記の表のサンプルで示すように、集約クエリを指定した SELECT 文を記述します。
EJB QL で作成される ResultSet は、cmp-field
の値、または、cmp-field
値の集合だけを返します。Bean を返すことはできません。
さらに、cmp-field
と集約関数を組み合わせた場合、下記のサンプルに示すような強力なクエリを作成できます。
次の行 (Bean) は、各地区の従業員の給与を示しています。
表 E-1 カリフォルニア市内の従業員の給与を示す CMP フィールド
表 E-2 アリゾナ市内の従業員の給与を示す CMP フィールド
表 E-3 テキサス市内の従業員の給与を示す CMP フィールド
次の SELECT 文のクエリでは、ResultSet、集約関数 (AVG) とともに、GROUP BY 文と ORDER BY 文を使用し、複数カラム クエリの結果を降順ソートを使って取り出します。
SELECT e.location, AVG(e.salary)
FROM Finder EmployeeBean AS e
GROUP BY e.location
ORDER BY 2 DESC
このクエリは、各地区の従業員の平均給与を降順で示します。2 という数字は、ORDERBY
ソートを SELECT
文の 2 番目の項目で実行することを意味しています。GROUP BY
句は、e.location
属性に一致する従業員の平均給与を指定しています。
注意 : ResultSet を返すクエリ内で ORDERBY
の引数として使用できるのは整数だけです。WebLogic Server では、Bean を返すファインダ、または ejbselect()
内で ORDERBY
の引数として整数を使用することはできません。
WebLogic Server は、INDEX の使い方に関するヒントを Oracle Query オプティマイザに渡すことを可能にする EJB QL 拡張機能をサポートしています。この拡張機能を使用すると、データベース エンジンにヒントを提供できます。たとえば、検索先のデータベースが ORACLE_SELECT_HINT によって恩恵を受けることがわかっている場合は、ANY 文字列値を取り、その文字列値をデータベースに対するヒントとして SQL SELECT 文の後に挿入する ORACLE_SELECT_HINT 句を定義します。
このオプションを使用するには、この機能を使用するクエリを weblogic-cmp-jar.xml
の weblogic-ql
要素で宣言します。weblogic-ql
要素では、EJB-QL に対する WebLogic 固有の拡張機能を含むクエリを指定します。
WebLogic QL のキーワードおよび使い方は次のとおりです。
SELECT OBJECT(a) FROM BeanA AS a WHERE a.field > 2 ORDERBY a.field SELECT_HINT '/*+ INDEX_ASC(myindex) */'
この文は、Oracle のオプティマイザ ヒントを使用して次の SQL を生成します。
SELECT /*+ INDEX_ASC(myindex) */ column1 FROM ....
WebLogic QL ORACLE_SELECT_HINT 句では、単一引用符で囲まれた部分 (' ') が SQL SELECT の後に挿入されます。クエリ作成者は、引用符内のデータを Oracle データベースが確実に認識できるものにする必要があります。
WebLogic Server では、一連のアクセサ メソッドを使用します。これらのメソッドの名前の先頭には、set と get が付いています。WebLogic Server では、コンテナ管理によるフィールドの読み出しおよび修正にこれらのメソッドを使用します。コンテナによって生成されるこれらのクラスは、「get」または「set」で始まり、ejb-jar.xml
で定義されている永続フィールドの実際の名前を使用する必要があります。また、これらのメソッドは、public
、protected
、および abstract
として宣言します。
Query
インタフェースには、検索と実行の両方のメソッドがあります。検索メソッドは、EJBObjects を返すという点で標準の EJB メソッドと同じように機能します。実行メソッドは、個々のフィールドを選択できるという点でさらに Select
文のように機能します。
Query
インタフェースの戻り値の型は切断された ResultSet
です。つまり、返されたオブジェクトの情報には、ResultSet
がデータベース接続の開いた状態を維持しないことを除いて、ResultSet
の情報にアクセスするのと同じ方法でアクセスします。
Query
インタフェースのプロパティベースのメソッドでは、クエリに固有の設定を指定することができます。QueryProperties
インタフェースは標準の EJB クエリ設定を保持し、WLQueryProperties
インタフェースは WebLogic 固有のクエリ設定を保持します。
Query
インタフェースは QueryProperties
の拡張版ですが、実際の Query
実装は WLQueryProperties
を拡張したものなので、フィールド グループ設定を設定するコード リスト 8-15 の例のように安全にキャストできます。
コード リスト 8-15 WLQueryProperties でのフィールド グループ設定の設定
Query query=qh.createQuery(); ((WLQueryProperties) query).setFieldGroupName("myGroup"); Collection results=query.find(ejbql);
Query query=qh.createQuery(); Properties props = new Properties(); props.setProperty(WLQueryProperties.GROUP_NAME, "myGroup"); Collection results=query.find(ejbql, props);
EJB 1.1 を使用する既存のアプリケーションがある場合、コンテナ管理によるエンティティ EJB ではファインダ メソッド用に WLQL を使用できます。この節では、WLQL の一般的な処理についてのクイック リファレンスを提供します。WLQL の構文と EJB QL の構文の対応については、次の表を参考にしてください。
EJB QL クエリに、(明示的クロス積とは対照的な) 暗黙的クロス積が含まれる場合、EJB QL クエリは結果として空の値を返す場合があります。
SELECT OBJECT(e) FROM EmployeeBean AS e WHERE e.name LIKE 'Joe' OR e.acct.balance < 100
このクエリは AccountEJB
を参照していますが、AccountEJB
は FROM
句にリストされていません。このクエリの結果は、FROM
句に明示的にリストされた AccountEJB
のあるクエリの場合と同じです。
EJB QL のコンパイラ エラー メッセージでは、クエリのどの部分にエラーが生じているのかを特定できるビジュアルな表示が用意され、コンパイルごとに複数のエラーを報告できます。
エラーが報告されると、EJB QL は問題のある場所を記号 =>> <<= で囲んで示します。これらの記号は、次に示すサンプルのコンパイラ エラー報告では赤色で強調されています。
ERROR: Error from appc: Error while reading 'META-INF/FinderEmployeeBeanRDBMS.xml'. The error was:
Query:
EJB Name: FinderEmployeeEJB
Method Name: findThreeLowestSalaryEmployees
Parameter Types: (java.lang.String)
Input EJB Query: SELECT OBJECT(e) FROM FinderEmployeeBean e WHERE f.badField = '2' O
R (e.testId = ?1) ORDERBY e.salary
SELECT OBJECT(e ) FROM FinderEmployeeBean e
WHERE =>> f.badField <<= = '2' OR ( e.testId = ?1 ) ORDERBY e.salary
Invalid Identifier in EJB QL expression:
Problem, the path expression/Identifier 'f.badField' starts with an identifier: 'f'. The identifier 'f', which can be either a range variable identifier or a collection member identifier, is required to be declared in the FROM clause of its query or in the FROM clause of a parent query.
'f' is not defined in the FROM clause of either its query or in any parent query.
Action, rewrite the query paying attention to the usage of 'f.badField'.
クエリに複数のエラーが含まれていた場合、EJB QL では、1 回のコンパイル後にこれらのエラーを複数個報告できるようになりました。これまでは、コンパイラが報告できるエラーはコンパイル 1 回につき 1 つだけでした。後続のエラーの報告には、再コンパイルが必要でした。
![]() ![]() |
![]() |
![]() |