EclipseLinkを使用すると、リレーショナルや非リレーショナルのデータ・ソースに対して、Java EEおよびJava EE以外のアプリケーションの両方で問合せを使用して、永続オブジェクトまたはデータを作成、読取り、更新および削除できます。
この章の内容は次のとおりです。
一般的に、データ・ソースの問合せとは、データ・ソースの内容に対する操作の実行、データ・ソースの内容との相互作用を意味します。データ・ソースの問合せを行うには、次のことができる必要があります。
問い合せるデータ・ソースのネイティブな構文で操作を定義します。
制御された方法で操作を適用します。
操作によって結果が返された場合は、それを管理します。
問合せがEclipseLinkキャッシュにどのような影響を与えるのかも考慮する必要があります。
この項では、次の内容を含む、EclipseLinkに固有の問合せの概念について説明します。
Callオブジェクトは、データ・ソースに対する操作またはアクションをカプセル化します。EclipseLink APIによって、Structured Query Language (SQL)、Java Persistence Query Language (JPQL)、Extensible Markup Language (XML)などの様々なCallタイプが提供されます。
Callは、直接実行することも、あるいはDatabaseQueryのコンテキストで実行することもできます。
DatabaseQueryオブジェクトは、追加のカスタマイズ・オプションや最適化オプションとCallでカプセル化した操作を関連付ける抽象オブジェクトです。EclipseLinkでは、これらのオプションをCallから分離することによって、すべてのCallタイプにわたって高度な問合せ機能を利用できます。
問合せは、オブジェクトまたはデータに対して次のように定義できます。
オブジェクト・レベルの問合せは、オブジェクト固有で、データをドメイン・モデルのオブジェクトとして返します。これは、マップ済データ向きの問合せです。オブジェクト・レベルのDatabaseQuery問合せは、EclipseLinkで最も頻繁に使用されます。
データ・レベルの問合せは、データベース表を直接問い合せるために使用され、アンマップ・データを操作する場合に適切な方法です。
データ・レベルの問合せはRAWデータを返し、オブジェクト・レベルの問合せはドメイン・モデルのオブジェクトを返しますが、サマリー問合せはオブジェクトに関するデータを返します。EclipseLinkでは、特定の属性のみが移入されたオブジェクトのセットを返す部分オブジェクト問合せと、オブジェクトのセットの特定の属性に関する要約(ロールアップ)データを返すレポート問合せが提供されます。
特定のクラスに適用できる名前付き問合せを保存できるのみでなく、一般的なデータ・ソース操作用にEclipseLinkで定義されているデフォルトの操作をDescriptorQueryManagerによってオーバーライドすることもできます。
EclipseLinkの式を使用すると、ドメイン・オブジェクト・モデルに基づいて問合せの検索基準を指定できます。問合せを実行する際、EclipseLinkではこれらの検索基準を、使用しているプラットフォームに適した問合せ言語に変換します。
EclipseLink APIは、式をサポートする次の2種類のパブリック・クラスを提供します。
Expressionクラスは、単純な定数からブール・ロジックを伴う複雑な句まで、あらゆる式を表します。式の操作、グループ化および統合を行うことができます。
ExpressionBuilderクラスは、新しい式を構成するためのファクトリです。
選択基準は、DatabaseQueryのメソッドsetSelectionCriteriaを使用してExpressionとして指定したり、Expressionを取るファインダに指定できます。
EclipseLinkの式の使用方法の詳細は、第11章「EclipseLinkの式の理解」を参照してください。
問合せキーとは、データベース・フィールド名の、スキーマ非依存の別名です。問合せキーを使用する場合、スキーマに依存しない別名を使用したフィールドを参照できます。リレーショナル・プロジェクトにかぎっては、EclipseLinkではマップした属性すべてに対して問合せキーを自動的に作成します。問合せキーの名前は、オブジェクト・モデルで指定されたクラス属性の名前です。
問合せキーは、クラス・ディスクリプタまたはインタフェース・ディスクリプタで構成できます。問合せキーは、式で使用することや、可変1対1マッピングを問い合せるために使用できます。
デフォルトでは、EclipseLinkによって、マップされたすべての属性の問合せキーが作成されますが、一部の環境では独自の問合せキーを追加すると役立つこともあります。
Java Persistence Query Language (JPQL)は、JPAによって定義された問合せ言語です。JPQLは、SQLとほぼ同じですが、表や列のかわりにオブジェクト、属性およびリレーションシップに対して動作します。JPQLは、読取り(SELECT)に加え、バルク更新(UPDATE)や削除(DELETE)のために使用できます。JPQLは、(注釈またはXMLを通じて) NamedQueryで使用するか、EntityManager createQuery() APIを通じて動的問合せで使用できます。
JPQLの短所は、動的問合せで、Webフォームや動的コンテンツから文字列を動的に連結して問合せを作成する必要があることです。また、JPQLは実行時までチェックされないので、タイプミスが多くなります。これらの短所は、次の項で説明する問合せ基準APIを使用すればある程度補えます。
詳細は、JPA仕様の第4章「Query Language」を参照してください。
http://jcp.org/en/jsr/detail?id=317
選択問合せは、データベースからオブジェクトを読み取るために使用できます。選択問合せによって、単一のオブジェクトまたはデータ要素、オブジェクトまたはデータ要素のリスト、複数のオブジェクトおよびデータのオブジェクト配列を返すことができます。
SELECT句には、オブジェクト式、属性式、関数、下位選択、コンストラクタおよび集計関数を含めることができます。
集計関数には、オブジェクトのセットに関するサマリー情報を含めることができます。これには、MIN、MAX、AVG、SUM、COUNTがあります。これらの関数を使用して、単一の結果を返すか、GROUP BYと組み合せて使用して複数の結果を返すことができます。
FROM句では、問合せ対象を定義します。標準的なFROM句には、問合せ対象のエンティティ名が含まれ、それに別名が割り当てられます。
JPQLでは、複数のルート・レベル・オブジェクトを問い合せることができます。これを実行する場合、2つの表のデカルト積になる可能性があるため、注意する必要があります。WHEREまたはON句では、なんらかの方法で2つのオブジェクトの結合を保証する必要があります。
JPQLで使用されるエンティティ名は、@Entity注釈またはXMLの名前属性から取得されます。デフォルトでは、単純なエンティティ・クラス名になります。EclipseLinkでは、エンティティの完全修飾クラス名も使用できます。
JOIN句も、FROM句で使用できます。JOIN句では、任意のオブジェクトのリレーションシップを問合せに結合して、WHERE句で使用できるようにします。JOINでは、FETCHオプションが含まれないかぎり、リレーションシップはフェッチされません。
JOINは、OneToOne、ManyToOne、OneToMany、ManyToManyおよびElementCollecitonマッピングとともに使用できます。コレクション・リレーションシップとともに使用すると、同じリレーションシップを複数回結合して、複数の独立値を問い合せることができます。
FETCHオプションをJOINで使用すると、1回の問合せで関連するオブジェクトをフェッチできます。これによって、オブジェクトのリレーションシップごとに追加の問合せを実行する必要がなくなり、リレーションシップがLAZYの場合、確実にそのリレーションシップがフェッチされます。EclipseLinkでは、問合せのヒントを通じた一括フェッチもサポートされます。
JOIN FETCHでは、通常、別名が許可されます。別名は、結果のオブジェクトの作成方法に影響する可能性があるため、慎重に使用してください。オブジェクトは、問合せの方法にかかわらず、一般的に常に同じデータを保持している必要があり、これはキャッシュや整合性のために重要です。これは、別名がコレクション・リレーションシップに対するWHERE句で使用され、フェッチされる関連オブジェクトがフィルタされる場合にのみ問題になります。これは避ける必要がありますが、適切な場合もあります(キャッシュをバイパスするように設定されていることを問合せで確認する必要がある場合など)。
デフォルトでは、JPQLのすべての結合はINNER結合です。つまり、リレーションシップを含まない結果は、問合せ結果からフィルタされます。これを回避するには、LEFTオプションを使用して結合をOUTER結合として定義します。
結合に使用されるJOIN条件は、マッピングの結合列から取得されます。つまり、JPQLユーザーは、通常、すべてのリレーションシップの結合方法を認識している必要はありません。一部の状況(通常は外部結合の場合)では、結合条件に別の条件を追加するのが適切です。これは、ON句を通じて実行できます。EclipseLinkでは、2つのルート・レベルのオブジェクト間でのON句の使用もサポートされます。
INNER結合では、EclipseLinkによって、通常はWHERE句に結合条件が追加されますが、これはDatabasePlatformで構成できます。
ORDER BYでは、結果の順序を指定できます。複数の値を昇順(ASC)または降順(DESC)で順序付けることができます。EclipseLinkでは、ORDER BY句で関数や下位選択などの操作を使用できます。EclipseLinkでは、ORDER BYでオブジェクト式を使用できます。エンティティ・オブジェクトは、IDで順序付けられ、埋込み可能オブジェクトは、すべてのフィールドで順序付けられます。EclipseLinkでは、NULLの順序付けも指定できます(FIRSTまたはLAST)。
GROUP BYでは、オブジェクトのセットに関してサマリー情報を計算できます。GROUP BYは、通常、集計関数と組み合せて使用します。EclipseLinkでは、GROUP BY句でオブジェクト、関数および下位選択の使用がサポートされます。
HAVING句では、GROUP BYの結果をフィルタできます。EclipseLinkでは、HAVING句で比較、オブジェクト、関数および下位選択の使用がサポートされます。
WHERE句は、返される結果をフィルタする条件を定義するため、通常は問合せの主要部分です。WHERE句では、比較操作、論理操作、関数、属性、オブジェクトおよび下位選択を使用できます。比較操作には、=、<、>、<=、>=、<>、LIKE、BETWEEN、IS NULLおよびINが含まれます。NOTも、任意の比較操作(NOT LIKE、NOT BETWEEN、IS NOT NULL、NOT IN)と組み合せて使用できます。論理操作には、AND、ORおよびNOTが含まれます。
EclipseLinkでは、正規表現の比較を実行するためのREGEXP操作もサポートされます(データベースが正規表現をサポートしている必要があります)。EclipseLinkでは、任意の操作で関数および下位選択を使用できます。
IN操作では、値またはパラメータのリスト、単一のリスト・パラメータまたは下位選択を使用できます。
下位選択は、単一の値が返される場合、またはALLやANYオプションが使用される場合、任意の操作と組み合せて使用できます。ALLは、下位選択で返されるすべての要素について操作がTrueである必要があることを示し、ANYは、下位選択で返されるいずれかの要素について操作がTrueである必要があることを示します。
EclipseLinkでは、オブジェクトに対して=、<>、IS NULL、IS NOT NULL、INおよびNOT IN操作が可能です。INがオブジェクトに対して使用され、オブジェクトにコンポジットIDが含まれる場合、データベースでネストしたINリストがサポートされている必要があります。
UPDATE文を使用して、エンティティのバルク更新を実行できます。この文は、単一のエンティティ・タイプに対して動作し、WHERE句の条件に従ってエンティティの1つ以上の単一値プロパティを設定します。更新問合せは、SQL UPDATE文と同等ですが、JPQLの条件式を使用します。
更新問合せでは、結合を使用できませんが、下位選択はサポートされます。OneToOneおよびManyToOneリレーションシップは、WHERE句で横断できます。コレクション・リレーションシップは、引き続き下位選択が含まれるWHERE句でEXISTSを使用することで問い合せることができます。更新問合せでは、オブジェクトまたはその埋込み可能オブジェクトの属性のみを更新でき、そのリレーションシップは更新できません。複雑な更新問合せは、データベースの更新サポートに依存し、一部のデータベースでは一時表が使用されることもあります。
更新問合せは、バルク更新でのみ使用する必要があり、オブジェクトの通常の更新は、トランザクション内でオブジェクトのsetメソッドを使用し、変更をコミットすることで行う必要があります。
更新問合せでは、データベースで変更された行の数が返されます(行カウント)。
永続性コンテキストは、更新操作の結果を反映するように更新されません。トランザクション・スコープの永続性コンテキストを使用する場合、トランザクションのバルク操作をすべて単独で実行するか、それがトランザクションでの最初の操作である必要があります。その理由は、永続性コンテキストによってアクティブに管理されるエンティティは、データベース・レベルで発生した実際の変更を認識しないためです。
更新問合せに一致する共有キャッシュのオブジェクトは、後続の永続性コンテキストが更新済データを認識できるように無効化されます。
DELETE文を使用して、エンティティのバルク削除を実行できます。削除問合せは、SQL DELETE文と同等ですが、JPQLの条件式を使用します。
削除問合せでは、結合を使用できませんが、下位選択はサポートされます。OneToOneおよびManyToOneリレーションシップは、WHERE句で横断できます。コレクション・リレーションシップは、引き続き下位選択が含まれるWHERE句でEXISTSを使用することで問い合せることができます。複雑な削除問合せは、データベースの削除サポートに依存し、一部のデータベースでは一時表が使用されることもあります。
削除問合せは、バルク削除でのみ使用する必要があり、オブジェクトの通常の削除は、EntityManager remove() APIのコールを通じて実行する必要があります。
削除問合せでは、データベースで削除された行の数が返されます(行カウント)。
|
注意: 削除問合せは多相です(削除問合せの基準に一致するすべてのエンティティ・サブクラス・インスタンスが削除されます)。ただし、削除問合せでは、カスケード・ルールは考慮されません(問合せとそのサブクラスで参照されているタイプ以外のエンティティは、そのエンティティにカスケード削除が有効化されている他のエンティティに対するリレーションシップがあっても削除されません)。削除問合せでは、結合表およびコレクション表から行が削除されます。 |
永続性コンテキストは、削除操作の結果を反映するように更新されません。トランザクション・スコープの永続性コンテキストを使用する場合、トランザクションのバルク操作をすべて単独で実行するか、それがトランザクションでの最初の操作である必要があります。その理由は、永続性コンテキストによってアクティブに管理されるエンティティは、データベース・レベルで発生した実際の変更を認識しないためです。
削除問合せに一致する共有キャッシュのオブジェクトは、後続の永続性コンテキストが削除済オブジェクトを認識できないように無効化されます。
JPAでは、名前付きパラメータと位置パラメータが定義されています。名前付きパラメータは、JPQLで:<name>という構文を使用して指定できます。位置パラメータは、JPQLで?または?<position>という構文を使用して指定できます。位置パラメータは、位置0ではなく1から開始します。
リテラル値は、標準のJavaタイプについてJPQLでインライン指定できます。一般的には、インライン値のかわりにパラメータを使用する方が適切です。インライン引数では、JPQLがJPQLパーサー・キャッシュの利点を得ることができず、アプリケーションがJPQLインジェクション攻撃に対して脆弱になる可能性があります。
Javaタイプごとに、その独自のインライン構文が定義されています。
String: '<string>'
文字列内で' (引用符)文字を定義するには、引用符を二重引用符にします('Baie-D''Urfé'など)。
Integer: +|-<digits>
Long: +|-<digits>L
Float: +|-<digits>.<decimal><exponent>F
Double: +|-<digits>.<decimal><exponent>D
Boolean: TRUE | FALSE
Date: {d'yyyy-mm-dd'}
Time: {t'hh:mm:ss'}
Timestamp: {ts'yyyy-mm-dd hh:mm:ss.nnnnnnnnn'} -
Enum: package.class.enum
null: NULL
JPQLでは、複数のデータベース関数がサポートされます。これらの関数は、名前と構文はデータベースに依存しませんが、データベースのサポートが必要です。データベースで同等の関数がサポートされる場合、標準のJPQL関数がサポートされます。データベースで関数を実行する方法が提供されていない場合は、サポートされません。数値演算関数(+、-、/、*)については、BEDMASルールが適用されます。
JPQLでは、サポート関数をSELECT、WHERE、ORDER BY、GROUP BYおよびHAVING句で使用できる以外に、他の関数の内部、比較演算子、コンストラクタでも使用できます。
EclipseLinkでは、JPA仕様に追加して複数の関数がサポートされます。EclipseLinkでは、FUNCTION、FUNCおよびOPERATORを通じて特定のデータベース関数をコールすることもできます。
EclipseLinkでは、基本的なJPQLでは使用できないデータベース操作を実行できる特殊なJPQL演算子がいくつか定義されています。これには次のものがあります。
FUNCTION
OPERATOR
SQL
COLUMN
これらの演算子の詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』の特殊な演算子に関する項を参照してください。
EclipseLinkでは、標準のJPA JPQLに対する多くの拡張機能が提供されています。これらの拡張機能によって、その多くがSQL標準の一部である追加のデータベース機能に対するアクセス、ネイティブのデータベース機能および関数に対するアクセス、およびEclipseLink固有の機能に対するアクセスが提供されます。
EclipseLinkのJPQL拡張機能には次のものが含まれます。
JPQLより少ない制限で、LIKE、IN、ORDER BY、コンストラクタ、関数などの操作内で下位選択および関数を使用可能
<>のかわりに!=を使用可能
データベース固有の関数をコールできるFUNCTION操作
継承のある関連エンティティをダウンキャストできるTREAT操作
EclipseLinkのデータベースに依存しない関数をコールできるOPERATOR操作
SQLとJPQLを組み合せることができるSQL操作
CASTおよびEXTRACT関数
正規表現による問合せのためのREGEXP関数
SELECTおよびFROM句での下位選択の使用
JOINおよびLEFT JOIN条件を定義するためのON句のサポート
独立エンティティ間の結合
JOIN FETCHでの別名の使用
マップされていない列での問合せを可能にするCOLUMN操作
マップされていない表での問合せを可能にするTABLE操作
UNION、INTERSECT、EXCEPTのサポート
=、<>、IN、IS NULLおよびORDER BYでのオブジェクト変数の使用
これらの拡張機能の詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のEclipseLinkの問合せ言語に関する項を参照してください。
EclipseLinkを使用すると、次の問合せ言語を使用して問合せを表現できます。
SQL問合せ
EclipseLinkの式(第11章「EclipseLinkの式の理解」を参照)
ほとんどの場合、特定の問合せ言語で問合せを直接構成できますが、可能であれば、適切なCallを使用してDatabaseQueryを構成し、Expressionオブジェクトを使用して選択基準を指定することをお薦めします。SQLで問合せを直接構成する方法が最も簡単な方法(簡単な操作またはアンマップ・データに対する操作)であるように思われますが、DatabaseQueryを使用した方法の場合、問合せをドメイン・オブジェクト・モデルに限定し、データ・ソース・スキーマ実装の詳細に依存しなくて済むという大きな利点があります。
問合せの構成には、Expressionを使用することをお薦めします。
SQLは、リレーショナル・データベース・データ・ソースを使用するアプリケーションで最も一般的な問合せ言語です。
SessionのメソッドexecuteSelectingCallおよびexecuteNonSelectingCallを使用してカスタムSQLを直接実行したり、適切なCallを使用してDatabaseQueryを構成することができます。
EclipseLinkでは、ストアド・プロシージャ、およびOracle Database、ストアド・ファンクションとともに使用できる様々なSQL Callオブジェクトを用意しています。
EclipseLinkでは、PL/SQLデータ・タイプを持つOracleストアド・プロシージャのPL/SQLコールもサポートします。
Java Persistence Criteria APIを使用すると、JPQLの文字列ベースのアプローチを使用せずに、オブジェクトベースの問合せ定義オブジェクトを構成して動的問合せを定義できます。Criteria APIによって、文字列ベースの第4世代言語アプローチよりJava言語との統合が容易になる動的問合せをプログラム的に作成できます。
Criteria APIには、タイプ制限モードとタイプなしモードという2つのモードがあります。タイプ制限モードでは、JPAメタモデル生成のクラスのセットを使用して、クラスの問合せ可能な属性を定義します(10.4.8項「メタモデル」を参照)。タイプなしモードでは、文字列を使用してクラスの属性を参照します。
Criteria APIは、動的問合せ専用で、メタデータまたは名前付き問合せでは使用できません。基準問合せは、動的問合せであり、静的な名前付き問合せや、EclipseLinkの解析キャッシュの利点を得ることができるパラメータ化された動的JPQLほどのパフォーマンスは得られません。
詳細は、JPA仕様の第6章「Criteria API」を参照してください。
http://jcp.org/en/jsr/detail?id=317
CriteriaBuilderは、Criteria APIの主要インタフェースです。CriteriaBuilderは、getCriteriaBuilder() APIを使用してEntityManagerまたはEntityManagerFactoryから取得されます。CriteriaBuilderを使用して、CriteriaQueryオブジェクトとその式を作成できます。Criteria APIでは、現在、選択問合せのみがサポートされます。
CriteriaQueryは、データベースの選択問合せを定義します。CriteriaQueryは、JPQL選択問合せのすべての句をモデル化します。あるCriteriaQueryの要素は、他のCriteriaQuerysで使用できません。CriteriaQueryは、EntityManager createQuery() APIとともに使用して、JPA問合せを作成できます。
where句は、返される結果をフィルタする条件(述語)を定義するため、通常は問合せの主要部分です。where句は、任意のPredicateオブジェクトでCriteriaQueryに対してwhere APIを使用することで定義されます。Predicateは、CriteriaBuilderに対して比較操作または論理操作を使用することで取得されます。isNull、isNotNullおよびin操作は、Expressionオブジェクトに対してもコールできます。not操作は、Predicateオブジェクトに対してもコールできます。
副問合せは、Criteria APIのselect、where、order、group byまたはhaving句で使用できます。副問合せは、subquery操作を使用してCriteriaQueryから作成されます。ほとんどのsubqueryの使用法では、CriteriaBuilderのexists、all、anyまたはsome操作か、in操作とともに使用しないかぎり、副問合せは単一の結果および値を返すように制限されます。
パラメータは、CriteriaBuilderでparameter APIを使用することで定義できます。JPAでは、名前付きパラメータと位置パラメータが定義されています。名前付きパラメータでは、パラメータのタイプと名前が指定されます。位置パラメータでは、パラメータのタイプのみが指定されます。位置パラメータは、位置0ではなく1から開始します。
Criteria APIでは、いくつかのデータベース関数がサポートされます。サポートされるすべての関数は、CriteriaBuilderで定義されます。一部の関数は、SQL準拠でない場合、一部のデータベースでサポートされないことがあり、同等の関数も提供されません。
Criteria APIでは、データベース関数ではない特殊な操作がいくつか定義されていますが、これらはJPAでは特殊な意味を持ちます。これらの操作の一部はCriteriaBuilderで定義され、一部は特定のExpressionインタフェースで定義されます。
JPAでは、ORMマッピング・メタデータの情報を問い合せるために実行時に使用できるメタモデルが定義されています。メタモデルには、クラスのマップ済属性のリストや、そのマッピングのタイプおよびカーディナリティが含まれます。メタモデルは、文字列を使用してクラス属性を参照するかわりに、Criteria APIと組み合せて使用できます。
JPAでは、コンパイル時にメタモデルにアクセスできる、JPAプロバイダ(IDE)によって生成される一連の"_"クラス(_MyEntity.javaなど)が定義されています。これによって、Criteria APIで型指定の静的変数を使用できます。これによって、テスト時ではなくコンパイル時に問合せの問題を捕捉することで、タイプミスの発生やアプリケーション・コードでの無効な問合せを削減できます。ただし、この場合、メタモデルの静的クラスを生成して開発サイクルの一部にする必要があるため、開発プロセスが複雑になります。
タプルでは、複数選択の問合せ結果が定義されます。通常、オブジェクト配列は、JPAの複数選択問合せによって返されますが、オブジェクト配列はそれほど有益なデータ構造ではありません。タプルは、名前または索引で結果を取得できるマップ状の構造です。
EclipseLinkのCriteria APIサポートにおける制限は、JPAの指定より少なくなっています。一般的に、副問合せおよびオブジェクト・パス式は、次のようにほとんどの場所で許可されます。
select、group byおよびorder句での副問合せ
関数と組み合せた副問合せの使用
オブジェクト・パス式と組み合せた使用
オブジェクト・パス式と組み合せたOrder byの使用
EclipseLinkのCriteria APIサポートは、EclipseLinkのネイティブExpression APIを基盤として成立しています。EclipseLinkには、JPA Expressionオブジェクトを対象としたネイティブのExpressionオブジェクトの変換を可能にするJpaCriteriaBuilderインタフェースが用意されています。これによって、EclipseLinkのネイティブのExpression APIをJPAのCriteria APIと組み合せることができます。
EclipseLinkのネイティブのExpression APIでは、次の追加機能が提供されます。
追加のデータベース関数(80を超えるデータベース関数のサポート)
カスタムのExpressionOperatorsの使用
Expression問合せ内へのSQLの埋込み
from句での下位選択の使用
ON句のサポート
マップされていない列および表へのアクセス
履歴問合せ
EclipseLinkのExpressionsは、EclipseLinkのDatabaseQuerysと組み合せて追加機能を提供できます。
union、intersectおよびexcept句
句による階層接続
一括フェッチ
JPAでは、エンティティ・オブジェクトまたはデータの問合せにSQLを使用できます。SQL問合せは、変換されずにデータベースに直接渡されます。SQL問合せは、データベース固有の構文を必要とする高度な問合せのために使用するか、JPQLやJavaよりSQL言語に慣れているユーザーによって使用できます。
SQL問合せは、createNativeQuery APIまたは名前付き問合せを使用してEntityManagerから作成されます。問合せオブジェクトは、他の任意のJPA問合せと同じように返され、実行されます。SQL問合せは、エンティティ・クラス用に作成することや、データのオブジェクト配列を返すことができます。エンティティを返す場合、SQL問合せによってエンティティのマッピングが予期している列名を返す必要があります(または、SqlResultSetMappingを使用できます)。SqlResultSetMappingでは、SQLの結果セットをエンティティ(またはエンティティおよびデータのセット)にマップできます。
SQL問合せを使用して、SQLまたはDML (データ操作言語)文を実行できます。結果を返すSQL問合せでは、getSingleResultまたはgetResultListを使用できます。結果を返さないSQL問合せでは、executeUpdateを使用する必要があります。executeUpdateは、トランザクション内でのみ使用できます。SQL問合せを使用して、データベース操作と、一部のストアド・プロシージャおよびファンクションを実行できます。出力パラメータを返すストアド・プロシージャまたは一部の複雑なストアド・プロシージャは、SQL問合せでは実行できません。EclipseLinkでは、ストアド・プロシージャ問合せを通じてストアド・プロシージャがサポートされます。
生成されるSQLに影響する問合せ設定および問合せヒントは、SQL問合せではサポートされません。サポートされない問合せヒントには、次のものがあります。
batch
history.as-of
inheritance.outer-join
sql.hint
join-fetch: join-fetchはサポートされますが、SQLですべての結合列を選択する必要があります。
fetch-group: fetch-groupはサポートされますが、SQLですべてのフェッチ列を選択する必要があります。
pessimistic-lock: pessimistic-lockはサポートされますが、SQLで結果行をロックする必要があります。
これらの拡張機能の詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のEclipseLinkの問合せ言語に関する項を参照してください。
SQL問合せのパラメータは、疑問符(?)を使用して区切る必要があります。索引付きパラメータのみがサポートされ、名前付きパラメータはサポートされません。索引は、?1などのデリミタで使用できます。パラメータ値は、setParameter APIを使用して問合せに設定されます。索引付きパラメータは、索引0ではなく1から開始します。
ネイティブSQL問合せは、NamedNativeQuery注釈または<named-native-query> XML要素を使用して注釈またはXMLで名前付き問合せとして定義できます。名前付きのネイティブSQL問合せは、任意の名前付き問合せと同じように実行されます。
結果列の名前が、エンティティ・マッピングで予期されている内容と一致しない場合、SqlResultSetMappingを使用してSQL問合せの結果をエンティティにマップできます。これは、単一のSQL問合せから複数のエンティティ(またはエンティティおよびデータ)を返す場合にも使用できます。EntityResultおよびFieldResultを使用して、エンティティ属性にSQL問合せの結果列をマップできます。ColumnResultを使用して、結果にデータ要素を追加できます。
SqlResultSetMappingsは、@SqlResultSetMapping注釈または<sql-result-set-mapping> XML要素を使用して、注釈またはXMLを通じて定義されます。これらは、名前を通じてネイティブSQL問合せから参照されます。
EclipseLinkには、式フレームワーク(EclipseLinkネイティブ問合せサポートとも呼ばれる)が用意されていて、この機能では、JPQLでサポートされていない問合せを記述する際に、SQLのかわりにデータベースに中立な形で問合せを表現できます。データベースにアクセスする場合、EclipseLinkの式は次の点でSQLよりも優れています。
データベースが抽象化されるため、式の方が管理が容易です。
ディスクリプタまたはデータベース表に変更を加えても、アプリケーションの問合せ構造に影響を与えません。
式では、Javaの通常のコール方法に似せてQueryインタフェースを標準化するため、読みやすさが向上します。
式を使用すると、読取り問合せによって、同じリレーションシップを共有する2つのクラスの間で問合せを透過的に行うことができます。これらのクラスがデータベース内の複数の表に格納されている場合、EclipseLinkは適切な結合文を自動的に生成し、両方の表から情報を返します。
式は複雑な操作を単純化します。
EclipseLinkでは、指定した式から適切なSQLが自動的に生成されます。
式フレームワークでは、式、データベース問合せ、コール・オブジェクトおよびネイティブ問合せを操作できます。
EclipseLinkのDatabaseQueryを使用したJPA問合せ
EclipseLinkのDatabaseQueryは、オブジェクト・レベルおよびデータ・レベルでの読取りおよび書込みを含む、データベース問合せの様々な要件を処理するための強力なAPIが用意された問合せオブジェクトです。
EclipseLinkのコール・オブジェクトを使用したJPA問合せ
DatabaseQueryのメソッドsetCallを使用すると、SQLストアド・プロシージャおよびストアド・ファンクションなど、様々なデータ・ソースのオプションに対応した、独自のEclipseLink Callを定義できます。
ネイティブ問合せの名前付きパラメータ
EclipseLinkでは、EclipseLinkの#表記規則を使用して、ネイティブ問合せに名前付きパラメータを指定できます。
ネイティブ問合せのJPQL位置パラメータ
EclipseLinkでは、Java Persistence Query Language (JPQL)の位置パラメータの?n表記規則を使用して、番号別にパラメータを指定することによって、ネイティブ問合せに位置パラメータを指定できます。
ネイティブ問合せのJDBCスタイル位置パラメータ
EclipseLinkでは、JDBCスタイルの位置パラメータの?表記規則を使用して、ネイティブ問合せに位置パラメータを指定できます。
問合せヒントを使用して、JPA問合せをカスタマイズまたは最適化できます。EclipseLinkのすべての問合せヒントは、org.eclipse.persistence.configパッケージのQueryHintsクラスで定義されます。
EclipseLinkで使用できる問合せヒントの詳細は、『Oracle Fusion Middleware Oracle TopLink Java Persistence API (JPA)拡張機能リファレンス』のJPA問合せカスタマイズの拡張機能に関する項を参照してください。JPA仕様の10.3.1項「NamedQuery Annotation」も参照してください。
http://jcp.org/en/jsr/detail?id=317
EclipseLinkのJPA問合せヒントを使用して、次のことを行えます。
JPA問合せの作成
@QueryHint注釈を使用したJPA問合せの指定
ヒントを設定する場合、次のようなorg.eclipse.persistence.configパッケージの適切な構成クラスのpublic static finalフィールドを使用して、値を設定できます。
HintValues
CacheUsage
PessimisticLock
QueryType
問合せのキャストを使用して、JPAまたはORMの使用時にサブクラスの属性全体を問い合せます。この機能は、JPQL、EclipseLinkの式およびCriteria APIで使用できます。
JPA 2.0以上では、結果または問合せを特定のサブクラスのものに制限できます。たとえば、式フレームワークでは、Expression.type(Class)が提供されます。
JPA 2.0以上では、JPA Criteria APIには、キャスト演算子のExpression.as(type)が含まれます。この式では、汎用内でタイプの一致を可能にする単純なキャストが実行されます。
EclipseLinkは、Expression.as(type)を使用してキャストを実行できるようにCriteria APIを拡張しています。asメソッドによって階層が確認され、タイプがコールされている式のタイプのサブクラスである場合、キャストが実装されます。
JOINノードでキャストをコールすると、そのノードは永続的に変更されます。たとえば、前述の例では、join.as(LargeProject.class)のコール後に、結合はLargeProjectを参照します。
Expression.as(Class)は、ダウンキャストにも使用できます。Expression.as(Class)を使用する場合の動作は、次のとおりです。
キャスト先のクラスが、キャスト対象の問合せキーのクラスのサブクラスではない場合、問合せ実行時に例外がスローされます。
キャストは、ObjectExpressions (QueryKeyExpressionおよびExpressionBuilder)でのみ許可されます。キャストの親の式は、ObjectExpressionとする必要があります。
キャストでは、変更されるObjectExpressionと同じ外部結合設定を使用します。
キャストでは、親の式を変更します。その結果、パラレル式でキャストを使用する場合、親の式の新しいインスタンスを使用する必要があります。
キャストは、TablePerClass継承ではサポートされません。
キャストを実行する問合せでは、タイプを慎重に確認してください。
EclipseLinkでは、キャストで単一のタイプが生成される場合、自動的にタイプ情報が追加されますが、階層の中間にあるクラスの場合、タイプ情報はSQLに追加されません。
EclipseLinkをOracle Databaseとともに使用する場合は、EclipseLinkアプリケーション内から次のOracle固有の問合せ機能を使用できます。
Oracleでは、データベース・サーバーのSQLオプティマイザの動作を変更できる、ヒントというSQL問合せの追加機能を指定できます。これを使用すると、通常オプティマイザで行われる設定を変更できます。ヒントを使用して、結合文の結合順序やSQLコールの最適化方法などを指定します。
ヒントを指定するには、DatabaseQueryのメソッドsetHintStringを使用します。
詳細は、使用しているデータベースのパフォーマンス・チューニング・ガイドを参照してください。
Oracleデータベースの階層問合せメカニズムを使用すると、階層順序に基づいてデータベースの行を選択できます。たとえば、特定の従業員の行、その従業員が管理する人々の行、その人々に管理される従業員の行などの順序で読取りを行う問合せを設計できます。
DatabaseQueryのサブクラスReadAllQueryのメソッドsetHierarchicalQueryClauseを使用して、階層問合せ句を指定します。
EclipseLinkをOracle9i Database以降とともに使用する場合、特別な履歴セッションを取得できます(このセッションでは、過去の特定時刻までのすべてのオブジェクトが読み取られ、ある期間にどのようにオブジェクトが変更されているかについての条件を付けた読込み問合せを表現できます)。
ストアド・ファンクションは、ストアド・プロシージャのすべての機能を提供するのみでなく値も返せるOracle Databaseのメカニズムです。