| Oracle® Fusion Middleware Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発 12c (12.2.1.1.0) E77277-02 |
|
![]() 前 |
findByPrimaryKey()以外のすべてのファインダ・メソッドの問合せをデプロイメント記述子で作成できます。findByPrimaryKeyは、EJBコンテナで自動的に処理されます。
この付録の内容は次のとおりです。
デプロイメント記述子では、EJB QL問合せ文字列を使用して、EJB 2.xのエンティティBeanの各ファインダ問合せを定義する必要があります。WebLogic Query Language (WLQL)をEJB 2.xエンティティBeanで使用することはできません。WLQLは、EJB 1.1のコンテナ管理による永続性で使用することを想定しています。WLQLおよびEJB 1.1のコンテナ管理による永続性の詳細については、「EJB 1.1 CMP用のWebLogic問合せ言語(WLQL)の使用」を参照してください
WebLogic Serverには、標準のEJB QLの拡張であり、SQLに似たWebLogic QLという言語が用意されています。queryは、weblogic-ql要素を使用して、weblogic-cmp-jar.xmlデプロイメント記述子に定義します。
ejb-jar.xmlファイルには、weblogic-cmp-jar.xmlファイルのweblogic-ql要素に対応する問合せ要素が必要です。ただし、weblogic-cmp-jar.xmlの問合せ要素の値は、ejb-jar.xmlの問合せ要素の値をオーバーライドします。
以下のトピックでは、EJB 2.x 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';
EJB QLのORDER BY句は、Finderメソッドと連携して、選択におけるCMPフィールドの選択順序を指定するキーワードです。
例G-1 idによる順序付けを指定するORDER BY
ORDER BY SELECT OBJECT(A) from A for Account.Bean ORDER BY A.id
次のように、複数のフィールドに対してORDER BYに昇順[ASC]か降順[DESC]かを指定することもできます。順序を指定しない場合、ORDER BYはデフォルトとして昇順を使用します。
例G-2 idによる順序付けを指定するORDER BY (昇順/降順指定)
ORDER BY <field> [ASC|DESC], <field> [ASC|DESC] SELECT OBJECT(A) from A for Account.Bean, OBJECT(B) from B for Account.Bean ORDER BY A.id ASC; B.salary DESC
WebLogic Serverでは、EJB QLのサブ問合せの次のような機能をサポートしています。
サブ問合せの戻り値の型
単一のcmp-field
集約関数
単純主キーを持つBean
比較オペランドとしてのサブ問合せ
相関サブ問合せ
非相関サブ問合せ
サブ問合せでのDISTINCT句
WebLogic QLとサブ問合せの関係は、SQL問合せとサブ問合せの関係に似ています。WebLogic QLのサブ問合せは、外部WebLogic QL問合せのWHERE句内で使用してください。若干の例外はありますが、サブ問合せの構文はWebLogic QL問合せのものとほぼ同じです。
WebLogic QLを指定する手順については、「EJB QLのEJB 2.x 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句で宣言される識別子がユニークでなければなりません。これはつまり、サブ問合せの内側で前にローカルに宣言した識別子をそのサブ問合せで再び宣言することはできないということです。
たとえば、次の例は無効です。EmployeeBeanが問合せとサブ問合せの双方で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サブ問合せの戻り値の型は、次のような各種の型のいずれかになります。
単一のcmp-field型のサブ問合せ
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つだけ選択しています。
集約関数の詳細については、「集約関数の使用」を参照してください
単純主キーを持つBean
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]EXISTS)
および
算術演算子(<、>、<=、>=、=、および該当部分すべてを表す<>)
[NOT]IN
[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比較演算子は、サブ問合せオペランドによって返された集合が空かどうか検査します。
サブ問合せが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_num 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
特定のitemIdに対し、サブ問合せはその品目の注文の最高数を返します。サブ問合せが返している集合が、「=」演算子に必要な1つの値となっている点に注意してください。
メインの問合せの「=」演算子では、これと同じitemIdに対し、どの注文のOrderItem.quantityOrderedが副問合せから戻された注文の最高数に等しいかを調べています。最終的に、特定の品目について注文が最高数である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)
副問合は、特定のorderIdに対し、そのorderIdで注文された各品目のorderItem.quantityOrderedの集合を戻します。メインの問合せの「>」ALL演算子は、各品目のorderItem.quantityOrderedが副問合せから戻された集合内のすべての値を上回っている注文すべてを探しています。最終的にメイン問合せは、すべてのorderItem.quantityOrderedが入力された注文の各orderItem.quantityOrderedを上回るすべての注文を戻します。
注意:
副問合せが複数の値を持つ結果を返す可能性があるため、「>」演算子ではなく、「>」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の算術関数をサポートしています。WebLogic QLを指定する手順については、「EJB QLのEJB 2.x WebLogic QL拡張機能の使い方」を参照してくださいこれらの例は、算術関数を指定するSELECT文で使用します。
表G-1 算術関数
| 算術関数 | 説明 |
|---|---|
|
数値(int、double、float)の絶対値を返します。 |
|
|
|
平方根を返します。 |
注意:
EJB QL算術関数は、DB2では問合せパラメータと一緒に使用できません。
WebLogic Serverでは、WebLogic QLの集約関数をサポートしています。これらは、WHERE句のような問合せの一部ではなく、SELECT句のターゲットとして使われるのみです。集約関数の振る舞いはSQL関数と似ています。これらの関数は、問合せのWHERE条件によって返されるBeanの外側で評価されます。
WebLogic QLを指定する手順については、「EJB QLのEJB 2.x WebLogic QL拡張機能の使い方」を参照してくださいこれに従って、次の表のサンプルのように、集約関数を指定したSELECT文を記述します。
サポートされている関数とサンプル文のリストを次に示します。
表G-2 集約関数
| 集約関数 | 有効な引数データ型 | 説明 | サンプル文 |
|---|---|---|---|
|
|
このフィールドの最小値を返します。 |
この文では、入力された特定のサイズの最安値を選択しています。 |
|
|
このフィールドの最大値を返します。 |
この文では、ロサンゼルス市内の販売代理人それぞれが担当する顧客数の中の最大値を選択しています。 |
|
numeric |
このフィールドの平均値を返します。 |
この文では、コンピュータ科学分野の書籍の平均価格を選択しています。 |
|
numeric |
このフィールドの合計を返します。 |
この文では、ロサンゼルス市内の販売代理人が担当している顧客の合計数を取得しています。 |
|
numeric |
フィールドの発生数を返します。 |
この文では、100万ドル以上の非公開取引の数を取得しています。 |
注意:
このリリースのWebLogic Serverでは、以下の条件がすべて真の場合、ObjectNotFoundExceptionが返されます。
集約問合せでSUM、AVG、MAX、またはMIN演算子が使用されている
選択メソッドの結果タイプがプリミティブである
集約関数を適用できる値が存在しない
9.0より前のリリースのWebLogic Serverでは、上記の条件がすべて真の場合、0が返されました。
SQL仕様では、集約と共に個々のフィールドを選択する問合せにはGROUP BY句を指定する必要があります。
次の手順で、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.x WebLogic QL拡張機能の使い方」を参照してくださいこの手順に従って、上に示した問合せのようにResultSetを指定します。また、同様にこれに従って、下記の表のサンプルで示すように、集約問合せを指定したSELECT文を記述します。
EJB QLで作成されるResultSetは、cmp-fieldの値、または、cmp-field値の集合だけを返します。Beanを返すことはできません。
さらに、cmp-fieldと集約関数を組み合わせた場合、下記のサンプルに示すような強力な問合せを作成できます。
次の行(Bean)は、各地区の従業員の給与を示しています。
表G-3 カリフォルニア州内の従業員の給与を示すCMPフィールド
| 名前 | 地区 | 給与 |
|---|---|---|
Matt |
CA |
110,000 |
Rob |
CA |
100,000 |
表G-4 アリゾナ州内の従業員の給与を示すCMPフィールド
| 名前 | 地区 | 給与 |
|---|---|---|
Dan |
AZ |
120,000 |
Dave |
AZ |
80,000 |
表G-5 テキサス州内の従業員の給与を示すCMPフィールド
| 名前 | 地区 | 給与 |
|---|---|---|
Curly |
TX |
70,000 |
Larry |
TX |
180,000 |
Moe |
TX |
80,00 |
注意:
各行が1つのBeanを表します。
次の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という数字は、ORDER BYソートをSELECT文の2番目の項目で実行することを意味しています。GROUP BY句は、e.location属性に一致する従業員の平均給与を指定しています。
ResultSetは、次のように降順で並んでいます。
| 地区 | 平均 |
|---|---|
AZ |
100,000 |
CA |
105,000 |
TX |
110,000 |
注意:
ResultSetを返す問合せ内でORDER BYの引数として使用できるのは整数だけです。WebLogic Serverでは、Beanを返すファインダ、またはejbselect()内でORDER BYの引数として整数を使用することはできません。
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 ORDER BY a.field SELECT_HINT '/*+ INDEX_ASC(myindex) */'
この文は、Oracleのオプティマイザ・ヒントを使用して次のSQLを生成します。
SELECT /*+ INDEX_ASC(myindex) */ column1 FROM ....
WebLogic QL ORACLE_SELECT_HINT句では、単一引用符で囲まれた部分(' ')がSQL SELECTの後に挿入されます。問合せ作成者は、引用符内のデータをOracleデータベースが確実に認識できるものにする必要があります。
Queryインタフェースには、検索と実行の両方のメソッドがあります。検索メソッドは、EJBObjectsを返すという点で標準のEJBメソッドと同じように機能します。実行メソッドは、個々のフィールドを選択できるという点でさらにSelect文のように機能します。
Queryインタフェースの戻り値の型は切断されたResultSetです。つまり、返されたオブジェクトの情報には、ResultSetがデータベース接続の開いた状態を維持しないことを除いて、ResultSetの情報にアクセスするのと同じ方法でアクセスします。
Queryインタフェースのプロパティ・ベースのメソッドでは、問合せに固有の設定を指定することができます。QueryPropertiesインタフェースは標準のEJB問合せ設定を保持し、WLQueryPropertiesインタフェースはWebLogic固有の問合せ設定を保持します。
QueryインタフェースはQueryPropertiesの拡張版ですが、実際のQuery実装はWLQueryPropertiesを拡張したものなので、フィールド・グループ設定を設定する例G-3の例のように安全にキャストできます。
例G-3 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の構文の対応については、次の表を参考にしてください。
表G-6 WLQLからEJB QLへの移行
| 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) ORDER BY e.salary
SELECT OBJECT(e ) FROM FinderEmployeeBean e
WHERE =>> f.badField <<= = '2' OR ( e.testId = ?1 ) ORDER BY 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'.