30.6.6. DeclaredSQL
DeclaredSQL は旧 JAWS CMP 1.1 エンジンの finder 宣言をベースにしていますが、CMP 2.0 用にアップデートされています。通常、この宣言を使い、EJB-QL や JBossQL では表示できない
WHERE
句を使ったクエリを制限しています。declared-sql 要素のコンテンツモデルは 図30.12「jbosscmp-jdbc declared-sql 要素のコンテンツモデル」に示しています。
図30.12 jbosscmp-jdbc declared-sql 要素のコンテンツモデル
- select:
select
要素は選択する対象を指定するもので、以下の要素で構成されています。- distinct:この空の要素がある場合、JBoss は
DISTINCT
キーワードを追加してSELECT
句を生成します。デフォルトでは、メソッドがjava.util.Set
を返した場合、DISTINCT
を使用するように設定されています。 - ejb-name: 選択するエンティティの
ejb-name
を示します。この項目は、クエリーが select メソッドの場合のみ必須です。 - field-name: 指定したエンティティから選択される CMP フィールドの名称です。デフォルトではエンティティ全体を選択するよう設定されています。
- alias: メインの select テーブルに使用するエイリアスを指定します。デフォルトは
ejb-name
を使用します。 - additional-columns: finder で任意のカラムの命令を実行、あるいは select の集約関数に対応するために選択されるカラムを宣言します。
- from:
from
要素は、生成済みのFROM
句に追加する SQL を宣言します。 - where:
where
要素は クエリー用のWHERE
句を宣言します。 - order:
order
要素はクエリー用のORDER
句を宣言します。 - other:
other
要素はクエリーの最後に追加する SQL を宣言します。
DeclaredSQL 宣言の例を以下に示します。
<jbosscmp-jdbc> <enterprise-beans> <entity> <ejb-name>GangsterEJB</ejb-name> <query> <query-method> <method-name>findBadDudes_declaredsql</method-name> <method-params> <method-param>int</method-param> </method-params> </query-method> <declared-sql> <where><![CDATA[ badness > {0} ]]></where> <order><![CDATA[ badness DESC ]]></order> </declared-sql> </query> </entity> </enterprise-beans> </jbosscmp-jdbc>
生成される SQL は次のようになります。
SELECT id FROM gangster WHERE badness > ? ORDER BY badness DESC
ご覧のように、JBoss はこのエンティティにプライマリキーを選択するのに必要な
SELECT
および FROM
句を生成します。ご希望であれば、自動生成された FROM
句の末尾に追加される FROM
句を指定することができます。以下に FROM
句を追加した DeclaredSQL 宣言の例を示します。
<jbosscmp-jdbc> <enterprise-beans> <entity> <ejb-name>GangsterEJB</ejb-name> <query> <query-method> <method-name>ejbSelectBoss_declaredsql</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </query-method> <declared-sql> <select> <distinct/> <ejb-name>GangsterEJB</ejb-name> <alias>boss</alias> </select> <from><![CDATA[, gangster g, organization o]]></from> <where><![CDATA[ (LCASE(g.name) = {0} OR LCASE(g.nick_name) = {0}) AND g.organization = o.name AND o.the_boss = boss.id ]]></where> </declared-sql> </query> </entity> </enterprise-beans> </jbosscmp-jdbc>
生成される SQL は次のようになります。
SELECT DISTINCT boss.id FROM gangster boss, gangster g, organization o WHERE (LCASE(g.name) = ? OR LCASE(g.nick_name) = ?) AND g.organization = o.name AND o.the_boss = boss.id
FROM
句はコンマで始まりますので注意してください。これは、コンテナーが生成された FROM
句の末尾に宣言した FROM
句を追加するためです。FROM
句は SQL JOIN
ステートメントで始まる場合もあります。select メソッドなので、選択されるエンティティを宣言する select
要素が必要です。エイリアスもクエリに対して宣言されますので、注意してください。エイリアスが宣言されない場合、table-name
をエイリアスとして使用します。つまり、SELECT
句が table_name.field_name
スタイルのカラム宣言になります。データベースベンダーによってはこの構文をサポートしていませんので、エイリアスの宣言を推奨します。任意でdistinct
要素により SELECT
句は SELECT DISTINCT
宣言を使用します。DeclaredSQL 宣言は CMP フィールドを選択する select メソッドでも使用することができます。
ここで
Organization
が運営している場所の郵便番号を返す select をオーバーライドする場合の例を以下に示します。
<jbosscmp-jdbc>
<enterprise-beans>
<entity>
<ejb-name>OrganizationEJB</ejb-name>
<query>
<query-method>
<method-name>ejbSelectOperatingZipCodes_declaredsql</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<declared-sql> <select> <distinct/> <ejb-name>LocationEJB</ejb-name> <field-name>zipCode</field-name> <alias>hangout</alias> </select> <from><![CDATA[ , organization o, gangster g ]]></from> <where><![CDATA[ LCASE(o.name) = {0} AND o.name = g.organization AND g.hangout = hangout.id ]]></where> <order><![CDATA[ hangout.zip ]]></order> </declared-sql>
</query>
</entity>
</enterprise-beans>
</jbosscmp-jdbc>
対応する SQL は次のようになります。
SELECT DISTINCT hangout.zip FROM location hangout, organization o, gangster g WHERE LCASE(o.name) = ? AND o.name = g.organization AND g.hangout = hangout.id ORDER BY hangout.zip
30.6.6.1. パラメーター
DeclaredSQL はまったく新しいパラメーター処理システムを採用し、エンティティと DVC パラメーターをサポートします。パラメーターは中括弧に入れ、1 ベースの EJB-QL パラメーターとは別の 0 ベースのインデックスを使用します。パラメーターには以下の 3 種類のカテゴリがあります。Simple、DVC と entity です。
- simple: シンプルパラメーターは既知(マッピング済みの)DVC やエンティティ以外のあらゆるタイプを指します。シンプルパラメーターは
{0}
などの引数のみを含みます。シンプルパラメーターが設定されている場合、パラメーターを設定する JDBC タイプは、エンティティに対するdatasourcemapping
で決定します。未知の DVC はシリアル化され、パラメーターとして設定されます。WHERE 句では BLOB 値の使用をサポートしていないデータベースがほとんどですので、注意してください。 - DVC: DVC パラメーターは既知の(マッピング済み)DVC になります。DVC パラメーターはシンプルプロパティ(別の DVC ではないもの)を逆参照する必要があります。たとえば、タイプ
ContactInfo
の CVS プロパティがある場合、有効なパラメーターの宣言は{0.email}
および{0.cell.areaCode}
になり、{0.cell}
にはなりません。パラメーターの設定に使用する JDBC タイプは、プロパティのクラスタイプとエンティティのdatasourcemapping
により決まります。パラメーターの設定に使用する JDBC タイプは、dependent-value-class
要素でこのプロパティに対して宣言した JDBC タイプになります。 - entity: エンティティパラメーターは、アプリケーションにある任意のエンティティになります。エンティティパラメーターは、DVC プライマリキーフィールドのシンプルプライマリキーフィールド、またはシンプルプロパティを逆参照する必要があります。たとえば、タイプ
Gangster
のパラメーターがある場合、有効なパラメーター宣言は{0.gangsterId}
になります。タイプContactInfo
のプライマリキーフィールドの名前が付いたエンティティがある場合、valid parameter
宣言は{0.info.cell.areaCode}
になります。エンティティのプライマリキーの構成要素であるフィールドのみ逆参照できます(今後のバージョンではこの制限がなくなる予定です)。パラメーターの設定に使用する JDBC タイプは、エンティティ宣言でこのフィールドに対して宣言した JDBC タイプになります。