ヘッダーをスキップ
Oracle Fusion Middleware Oracle TopLink開発者ガイド
11gリリース1(11.1.1)
B56246-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

108TopLink問合せの概要

TopLinkを使用すると、リレーショナルや非リレーショナルのデータ・ソースに対して、Java EEおよびJava EE以外のアプリケーションの両方で問合せを使用して、永続オブジェクトまたはデータを作成、読取り、更新および削除できます。

この章の内容は次のとおりです。

108.1 問合せのタイプ

表108-1は、TopLinkで作成できる問合せのタイプを示します。

表108-1 TopLink問合せのタイプ

問合せのタイプ 説明 Oracle JDeveloper
TopLink Workbench Java

セッション問合せ


この問合せは、オブジェクトに対する最も一般的なデータ・ソース・アクションの実行に使用される入力パラメータに基づいて、Sessionによって暗黙的に構成され、実行されます。

サポートされていない


サポートされていない


サポートされている

データベース問合せ


この問合せは、問合せオブジェクトの問合せとも呼ばれます。オブジェクトまたはデータのいずれかに対するデータ・ソース・アクションを実行するために作成し実行する、DatabaseQueryのインスタンスです。また、DatabaseQueryを微調整することもできます。それには、そのCallを作成し、構成します(108.9項「コール問合せ」を参照)。

サポートされていない


サポートされていない


サポートされている

名前付き問合せ


SessionまたはディスクリプタのDescriptorQueryManagerに名前付きで格納されるDatabaseQueryのインスタンスです。DescriptorQueryManagerでは、このインスタンスが1回のみ作成、プリコンパイルされます。その後、この問合せは、名前を使用して繰り返し実行することができます。

サポートされている
サポートされている
サポートされている

コール問合せ


開発者が作成するCallのインスタンスです。これは、データに対する制限されたデータ・ソース・アクションのみを実行するために、特別なセッションAPIを使用して直接実行するか、または、間接的にDatabaseQueryのコンテキストで実行します。TopLinkでは、カスタムSQL、ストアド・プロシージャ、EISインタラクションのCallインスタンスをサポートします。

サポートされている
サポートされている
サポートされている

リダイレクト問合せ


名前付き問合せで設定されたMethodBasedQueryRedirector(staticメソッドの名前および、このメソッドがパラメータとして定義されるClassをとる)のインスタンスです。この問合せを実行すると、staticメソッドが起動されます。

サポートされていない


サポートされていない


サポートされている

履歴問合せ


TopLink Expressionフレームワークの時間に関する機能を使用して、履歴セッションのコンテキストで実行される問合せです。

サポートされていない


サポートされていない


サポートされている

インタフェースと継承問合せ


インタフェースのタイプまたは継承階層のスーパー・クラスおよびサブクラスを参照する問合せです。

サポートされていない


サポートされていない


サポートされている

ディスクリプタ問合せマネージャ問合せ


DescriptorQueryManagerでは、各基本データ・ソース操作(作成、読取り、更新および削除)のデフォルトのDatabaseQueryを定義します。また、DatabaseQueryまたはそのCallのいずれかをカスタマイズするために使用できるAPIを提供します。

サポートされている
サポートされている
サポートされている

EJB 2.n CMPファインダ


Enterprise Beanを戻すEnterprise Beanのホーム・インタフェースで定義される問合せです。JPAQLCallEJBQLCallなど、JPA/EJB QLをとるCallを含め、任意のTopLink問合せタイプを使用してファインダを実装できます。

サポートされている
サポートされている
サポートされている

詳細は、次を参照してください。

108.2 問合せの概念

一般的に、データ・ソースの問合せとは、データ・ソースの内容に対する操作の実行、データ・ソースの内容との相互作用を意味します。データ・ソースの問合せを行うには、次のことができる必要があります。

また、TopLinkでは、問合せがTopLinkキャッシュにどのような影響を与えるのかも考慮する必要があります。詳細は、108.16項「問合せとキャッシュ」を参照してください。

この項では、次の内容を含む、TopLinkに固有の問合せの概念について説明します。

108.2.1 Call

TopLinkでは、Callオブジェクトがデータ・ソースへの操作をカプセル化します。TopLinkには、Structured Query Language(SQL)、Enterprise Java Bean Query Language(EJB QL)、Java Persistence Query Language(JP QL)、eXtensible Markup Language(XML)、および企業情報システム(EIS)など、様々なタイプのCallがあります。

Callは、直接実行することも、あるいはDatabaseQueryのコンテキストで実行することもできます。

108.2.2 DatabaseQuery

DatabaseQueryオブジェクトは、追加のカスタマイズ・オプションや最適化オプションとCallでカプセル化した操作を関連付ける抽象オブジェクトです。TopLinkでは、これらのオプションをCallから分離することによって、すべてのCallタイプにわたって高度な問合せ機能を利用できます。

詳細は、108.7項「データベース問合せ」を参照してください。

108.2.3 データ・レベルとオブジェクト・レベルの問合せ

TopLinkでは、問合せをオブジェクトまたはデータに対して次のように定義できます。

108.2.4 サマリー問合せ

データ・レベルの問合せが行データを返し、オブジェクト・レベルの問合せがドメイン・モデルのオブジェクトを返すのに対し、サマリー問合せはオブジェクトに関するデータを返します。TopLinkでは、部分オブジェクト問合せとレポート問合せを使用できます。部分オブジェクト問合せ(108.7.1.3項「部分オブジェクト問合せ」を参照)では、特定の属性のみを移入したオブジェクトのセットを返します。また、レポート問合せ(108.7.5項「レポート問合せ」を参照)では、オブジェクトのセットの特定の属性を要約またはロールアップしたデータを返します。

108.2.5 ディスクリプタ問合せマネージャ

特定のクラスに適用できる名前付き問合せを保存できるのみでなく(108.8項「名前付き問合せ」を参照)、一般的なデータ・ソース操作用にTopLinkで定義されているデフォルトの操作をDescriptorQueryManagerによってオーバーライドすることもできます。詳細は、108.13項「ディスクリプタ問合せマネージャ問合せ」を参照してください。

108.2.6 TopLinkの式

TopLinkの式を使用すると、ドメイン・オブジェクト・モデルに基づいて問合せの検索基準を指定できます。問合せを実行する際、TopLinkではこれらの検索基準を、使用しているプラットフォームに適した問合せ言語に変換します。

TopLinkは、式をサポートする次の2種類のパブリック・クラスを提供します。

  • Expressionクラスは、単純な定数からブール・ロジックを伴う複雑な句まで、あらゆる式を表します。式の操作、グループ化および統合を行うことができます。

  • ExpressionBuilderクラスは、新しい式を構成するためのファクトリです。

選択基準は、DatabaseQueryのメソッドsetSelectionCriteria108.7項「データベース問合せ」を参照)を使用してExpressionとして指定したり、Expressionを取るファインダ(108.15.7項「式ファインダ」を参照)に指定できます。

TopLinkの式の使用の詳細は、第110章「TopLinkの式の概要」を参照してください。

108.2.7 問合せキー

問合せキーとは、データベース・フィールド名の、スキーマ非依存の別名です。問合せキーを使用する場合、スキーマに依存しない別名を使用したフィールドを参照できます。リレーショナル・プロジェクトにかぎっては、TopLinkではマップした属性すべてに対して問合せキーを自動的に作成します。問合せキーの名前は、オブジェクト・モデルで指定されたクラス属性の名前です。

問合せキーは、クラス・ディスクリプタ(119.10項「問合せキーの構成」を参照)またはインタフェース・ディスクリプタ(119.11項「インタフェース問合せキーの構成」を参照)で構成できます。

式で問合せキーを使用して(110.4項「問合せキーと問合せ式」を参照)、可変1対1マッピングについて問い合せることができます(111.8項「可変1対1マッピングに対する問合せの使用」を参照)。

108.2.8 問合せ言語

TopLinkを使用すると、次の問合せ言語のいずれかを使用して問合せを表現できます。

ほとんどの場合、指定の問合せ言語で直接、問合せを構成できます。または、可能であれば、適切なCallを使用してDatabaseQueryを作成し、TopLink Expressionを使用して選択基準を指定します。問合せをSQLで直接構成する方法が最も簡単なアプローチのように見えますが(簡単な操作やマップされていないデータへの操作の場合は事実そのとおりです)、DatabaseQueryのアプローチを使用した方が、問合せをドメイン・オブジェクト・モデルに限定でき、データ・ソース・スキーマ実装の詳細への依存を避けられるという、大きな利点があります。

問合せの構成には、JP QLまたはExpressionを使用することをお薦めします。

108.2.8.1 SQL問合せ

SQLは、リレーショナル・データベース・データ・ソースを使用するアプリケーションで最も一般的な問合せ言語です。

SessionのメソッドexecuteSelectingCallおよびexecuteNonSelectingCallを使用してカスタムSQLを直接実行したり、適切なCallを使用してDatabaseQueryを構成することができます。

TopLinkでは、ストアド・プロシージャ、およびOracleデータベース、ストアド・ファンクションとともに使用できる様々なSQL Callオブジェクトを用意しています。詳細は、108.9.1項「SQLコール」を参照してください。

TopLinkでは、PL/SQLデータ・タイプを持つOracleストアド・プロシージャのPL/SQLコールもサポートします。詳細は、109.5項「StoredProcedureCallの使用」を参照してください。

108.2.8.2 EJB QL問合せ

EJB QLは、SQLと同様に問合せ言語ですが、SQLとは異なり、オブジェクト・モデルの観点から問合せを表したもので、これを使用すると、ユーザーはオブジェクト・モデル内の各抽象エンティティBeanの属性を使用して問合せを宣言できます。また、EJB QLには、エンティティBeanと依存オブジェクトの間で定義されているリレーションシップのナビゲーションを可能にするパス式が含まれます。

EJB QLには次のような利点があります。

  • データベース構造(表、フィールドなど)を知っている必要がありません。

  • データベースの表やフィールドを使用するかわりにエンティティBeanの属性を使用して、問合せを構成できます。

  • 問合せでリレーションシップを使用して、属性間をナビゲーションできます。

  • EJB QL問合せはデータベースに依存しないため、移植性があります。

  • SELECT句に参照クラスを指定できます。

EJB QL問合せの短所は、複雑な問合せを構成する場合に使用方法が難しいことです。

TopLinkでは、EJB QLの仕様が完全にサポートされています。


注意:

TopLinkでは、LOCATE文字列関数がサポートされ、この関数を使用して正しいSQLが生成されます。ただし、一部のデータ・ソースではLOCATEをサポートしていません。LOCATE文字列関数を使用する前に、データ・ソースのドキュメントを参照してください。

EJB QLは、EJB 2.0の仕様で最初に定義された標準的な問合せ言語です。このため、TopLinkでは、EJBファインダでEJB QL(108.15.8項「EJB QLファインダ」を参照)を使用して選択基準を指定できるようにしています。

通常、EJB QLはEJBに関連付けられていますが、TopLinkでは普通のJavaオブジェクトの問合せでEJB QLを使用して選択基準を指定することもできます。TopLinkで提供するEJB QL Callは、直接実行することも、あるいはDatabaseQueryのコンテキストで実行することもできます。詳細は、108.9.2項「EJB QLコール」および108.2.2項「DatabaseQuery」を参照してください。

108.2.8.3 JP QL問合せ

詳細は、『EclipseLink Developer's Guide』の「What You May Need to Know About Querying with Java Persistence Query Language」(http://wiki.eclipse.org/Developing_Applications_Using_EclipseLink_JPA_%28ELUG%29#What_You_May_Need_to_Know_About_Querying_with_Java_Persistence_Query_Language)を参照してください。

108.2.8.4 XML問合せ

TopLink XMLを使用して、OracleデータベースXMLTypeフィールドに格納されているXMLデータを問い合せることができます。詳細は、27.4項「XMLタイプへ直接マッピング」および110.2.4項「XMLType関数」を参照してください。

108.2.8.5 EISインタラクション

EIS Call108.9.3項「企業情報システム(EIS)インタラクション」を参照)を使用してTopLink問合せを実行すると、選択基準が、使用しているJCAアダプタに適したXML形式に変換されます。

XQuery言語がJCAアダプタでサポートされている場合、XQuery言語を使用できるようにするには、XQueryインタラクション(108.9.3.4項「XQueryInteraction」を参照)を直接またはDatabaseQueryのコンテキストで実行します。

108.2.8.6 例による問合せ

例による問合せは、簡単で直感的な問合せ表現方法です。例による問合せを指定するには、問合せの対象となる永続オブジェクトのサンプル・インスタンスを指定し、問い合せるデータ・メンバーにのみ適切な値を設定します。

例による問合せを使用すると、ダイレクト・マッピングまたは1対1リレーションシップ(ネストしているものを含む)を使用する属性を基準にオブジェクトを問い合せることができます。


注意:

例による問合せでは、これ以外のリレーションシップ・マッピング・タイプやEJB 2.n CMP Beanはサポートされません。

問合せの基準となる属性のみを設定し、その他の属性はすべてnullに設定します。デフォルトでは、サンプル・インスタンス内のnull、ゼロ(0)、空の文字列およびFALSEを含む属性は無視されます。QueryByExamplePolicy「QueryByExamplePolicyの定義」を参照)を指定することで、この値リストを変更し、例による問合せの他のオプションを定義できます。

例による問合せでは、AND演算子を使用して属性の比較を結合します。デフォルトでは、サンプル・インスタンスの属性値と、EQUALS演算子を使用する候補オブジェクトの対応する値を比較します。QueryByExamplePolicyを使用して、この動作を変更できます。

ReadAllQueryReadObjectQueryには、サンプル・オブジェクト・インスタンスを使用した選択基準を指定できる、setExampleObjectメソッドおよびsetQueryByExamplePolicyメソッドが用意されています。

詳細および例は、109.2.1.4項「例による問合せを使用したオブジェクトの読取り」を参照してください。

108.3 問合せの作成

Oracle JDeveloper、TopLink WorkbenchまたはJavaを使用し、TopLink APIを使用して、問合せを作成できます。

問合せには、渡された引数に基づいて暗黙的に作成され、1ステップで実行されるもの(たとえば、108.6項「セッション問合せ」で説明されているセッション問合せ)と、ユーザーが明示的に作成、構成および実行するもの(たとえば108.7項「データベース問合せ」)があります。

詳細は、次を参照してください。

108.4 問合せの実行

TopLinkでは、表108-2にまとめたセッションAPIを使用して、ほとんどの問合せを実行できます。

表108-2 問合せの実行に使用するセッション・メソッド

問合せのタイプ セッション・メソッド 長所と短所

セッション問合せ


readObject

readAllObjects

writeObject

writeAllObjects

deleteObject

deleteAllObjects

insertObject

updateObject

長所: オブジェクトに対して一般的なデータ・ソース操作を実行するには最も手軽な方法です。

短所: 問合せの実行とその結果を制御できる柔軟性の点で劣り、頻繁に実行する問合せでは非効率的です。

データベース問合せ

名前付き問合せ

リダイレクト問合せ


executeQuery

長所: 構成および実行に関して最も柔軟性に優れています。名前付き問合せに共通の効率性という利点があります。

短所: DatabaseQueryおよびCallオブジェクト(必要な場合)を明示的に作成し、構成する必要があります。

コール問合せ


executeSelectingCall

executeNonSelectingCall

長所: マップされていないデータに直接操作を適用できる便利な方法です。

短所: 問合せの実行とその結果を制御できる柔軟性が最も低く、生のデータ結果についてアプリケーションでより多くの処理を行う必要があります。



注意:

すべてのデータ・ソース操作は作業ユニットを使用して実行することをお薦めします。これがトランザクション、同時実行性および参照制約を管理する最も効率のよい方法です。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。

または、セッションAPIを直接使用して作業ユニット外で問合せを実行することもできますが、その場合は、トランザクション、同時実行性および参照制約をアプリケーション側で管理する責任が増大します。


セッション問合せを実行すると、TopLinkではDescriptorQueryManager問合せが実行されます。詳細は、108.13項「ディスクリプタ問合せマネージャ問合せ」を参照してください。

EJB 2.n CMP Beanで適切なファインダ・メソッドをコールする場合は、EJB 2.n CMPファインダを実行します。詳細は、108.15項「EJB 2.n CMPファインダ」を参照してください。


警告:

検証されていないSQL文字列がメソッド(たとえばsetSQLString(String sql)、readAllObjects(Class class, String sql)メソッド)に渡されるように許可すると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


詳細は、次を参照してください。

108.5 問合せ結果の処理

通常、TopLinkの問合せはJavaオブジェクトを結果セットとして返します。TopLink問合せでは、次のいずれかを返すことができます。

108.5.1 コレクション問合せの結果

コレクションとは、CollectionまたはMapのインスタンス内に格納されたJavaオブジェクトのグループです。

デフォルトでは、複数のオブジェクトを返す問合せは、その結果をVectorに返します。

問合せ結果をCollectionまたはMapの任意の具象インスタンスに返すように、TopLinkを構成できます。

コレクションの結果は、TopLinkのすべての問合せタイプでサポートされています。

コレクション問合せの結果の構成と処理の詳細は、109.10項「コレクション問合せの結果の処理」を参照してください。

108.5.2 レポート問合せの結果

ReportQuery(部分オブジェクト問合せの一種)は、データベースのレポート関数、およびプラットフォームでサポートされている機能を使用して選択したオブジェクトのサマリー・データを返します。レポート問合せではオブジェクトではなくデータが返されますが、返されたデータをオブジェクト・レベルで問い合せたり、指定したりすることができます。

デフォルトでは、ReportQueryは、ReportQueryResultオブジェクトのコレクション(108.5.1項「コレクション問合せの結果」を参照)を1つ返します。コレクションは1つのデータベース行に返されます。ReportQuery APIを使用して、ReportQueryがその結果を返す方法を構成できます。詳細は、109.11項「レポート問合せの結果の処理」を参照してください。

詳細は、次を参照してください。

108.5.3 ストリームとカーソルの問合せの結果

ストリームとはコレクションのビューであり、ファイル、デバイス、Vectorなどです。ストリームを使用すると、コレクションの要素に一度に1つずつ順にアクセスできます。これにより、1つのコレクションの全オブジェクトが同時にストリームに含まれることのないストリーム・クラスの実装が可能になります。

大きな結果セットは、収集して処理する際に、リソースを大量に消費します。パフォーマンスを向上させ、クライアントが返された結果をより確実に制御できるようにするには、カーソルまたはストリームを使用するようTopLink問合せを構成します。

カーソルとストリームは、DataReadQueryおよびReadAllQueryのすべてのサブクラスでサポートされています。

詳細は、111.11項「カーソルとストリームの問合せ結果の処理」を参照してください。

108.6 セッション問合せ

セッションには、表108-3に示すオブジェクト操作を実行するための問合せメソッドがあります。

表108-3 セッション・オブジェクト問合せのサマリー

セッション・タイプ 作成 読取り 更新 削除

UnitOfWork

registerObject

readObject

readAllObjects

なし

deleteObject

deleteAllObjects

Server

なし

なし

なし

なし

ClientSession

なし

readObject

readAllObjects

なし

なし

DatabaseSession

insertObject

readObject

readAllObjects

updateObject

writeObject

writeAllObjects

deleteObject

deleteAllObjects



注意:

すべてのデータ・ソース操作は作業ユニットを使用して実行することをお薦めします。これがトランザクション、同時実行性および参照制約を管理する最も効率のよい方法です。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。

これらのメソッドでは、次の入力パラメータに基づいてDatabaseQueryを暗黙的に作成して実行し、ObjectまたはObjectコレクションを返します。

これらのメソッドは、オブジェクトに対して最も一般的なデータ・ソース操作を実行するために手軽な方法です。


警告:

検証されていないSQL文字列をメソッドに渡すことを許可すると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


すべての構成可能オプションを使用して問合せを詳細に設定し、最適化するには、該当するDatabaseQueryを直接使用する必要があります。詳細は、108.7項「データベース問合せ」を参照してください。

詳細は、109.1項「セッション問合せの使用」を参照してください。

108.6.1 読取りセッション問合せ

読取り問合せでは、指定した選択基準に一致するObjectの最初のインスタンスを返し、すべて読取り問合せでは、そのようなインスタンスをすべて返します。

また、主キーを設定してドメインObjectを渡すと、TopLinkでは、そのオブジェクトを選択する読取り問合せを構成して実行します。これは、例による問合せの1つの形式です。例による問合せの詳細は、108.2.8.6項「例による問合せ」を参照してください。

詳細は、109.1.1項「セッション問合せを使用したオブジェクトの読取り方法」を参照してください。

108.6.2 オブジェクト・セッション問合せの作成、更新および削除

オブジェクトは作業ユニットを使用して作成および更新することをお薦めします。これがトランザクション、同時実行性および参照制約を管理する最も効率のよい方法です。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。

ただし、セッション問合せを使用してオブジェクトを作成および更新することもできます。このセッション問合せは、ユーザー設定項目など、リレーションシップを持たない単純な非ビジネス・オブジェクト・データを管理する際に、データベースで直接オブジェクトを変更できる便利な方法です。

オブジェクトが新規であることがわかっている場合は、insertObjectメソッドを使用することで、TopLinkでの存在チェックを省略できます。オブジェクトが新規かどうかわかっていない場合は、updateObjectwriteObjectまたはwriteAllObjectメソッドを使用します。必要に応じ、TopLinkにより存在がチェックされます。

書込みセッション問合せを実行すると、オブジェクトとその私有部分の両方がデータベースに書き込まれます。この動作を管理するには、対応するDatabaseQueryを使用します(108.7.3.7項「オブジェクト・レベルの変更問合せと私有部分」を参照)。

SessionのメソッドdeleteObjectを使用すると、特定のオブジェクトを削除できます。SessionのメソッドdeleteAllObjectsを使用すると、オブジェクトのコレクションを削除できます。指定された各オブジェクトとその私有部分のすべてが削除されます。deleteAllObjectsの場合、1つのトランザクションですべての削除が実行されます。

詳細は、109.1.2項「セッション問合せを使用したオブジェクトの作成、更新および削除方法」を参照してください。

108.7 データベース問合せ

すべてのセッション・タイプでは、次のいずれかのタイプのDatabaseQueryをとるexecuteQueryメソッドを使用できます。

DatabaseQueryのメソッドsetCallを使用すると、SQL(ストアド・プロシージャおよびストアド・ファンクションを含む)、EJB QL問合せおよびEISインタラクションなどの様々なデータ・ソースのオプションに対応した、独自のCallを定義できます。詳細は、108.9項「コール問合せ」を参照してください。

DatabaseQueryのメソッドsetSelectionCriteriaを使用すると、TopLinkのExpressionを使用して、選択基準を指定できます。詳細は、108.2.6項「TopLinkの式」を参照してください。

詳細は、109.2項「DatabaseQuery問合せの使用」を参照してください。

108.7.1 オブジェクト・レベルの読取り問合せ

ObjectLevelReadQueryを使用すると、データ・ソースに問い合せ、指定した選択基準に一致するObjectインスタンスを返すことができます。この項の内容は次のとおりです。

詳細は、109.2.1項「DatabaseQueryを使用したオブジェクトの読取り方法」を参照してください。

108.7.1.1 ReadObjectQuery

ReadObjectQueryを使用すると、データ・ソースに問い合せ、指定した選択基準に一致する最初のオブジェクトを返すことができます。

108.7.1.2 ReadAllQuery

ReadAllQueryを使用すると、データ・ソースに問い合せ、指定した選択基準に一致するすべてのオブジェクトのCollectionを返すことができます。

108.7.1.3 部分オブジェクト問合せ

デフォルトでは、ObjectLevelReadQueryが、読み取られたオブジェクトのすべての属性を返します。

選択したオブジェクトの、特定の属性のみを必要とする場合、ObjectLevelReadQueryのメソッドaddPartialAttributesを使用して部分オブジェクト問合せを作成できます。このメソッドを使用すると、オブジェクトが、指定した属性にのみ移入されて戻されるため、問合せのパフォーマンスが向上します。

アプリケーションでは、部分オブジェクト問合せを使用して、さらに選択を行うためのリストを作成することがよくあります。たとえば、40歳を超える全従業員の名前と住所を調べる問合せでは、オブジェクト(従業員)を部分的に表すデータ(名前と住所)のリストが返されます。通常は、次にこのリストを提示して、ユーザーがリストから必要なオブジェクトを1つ以上選択できるようにします。TopLinkでは常に主キー属性が組み入れられるため(部分属性として追加していない場合でも)、後で完全なオブジェクトを取得するのが簡単になります。

部分オブジェクト問合せを使用する際は、次の点を考慮してください。

  • 部分オブジェクトの編集とキャッシュはできません。

  • 指定されていない属性はnullのままになります。

  • 同じタイプの部分属性を2つ持つことはできません。

  • 問い合せるクラスと同じタイプの部分属性は追加できません。

選択したオブジェクトの、特定の属性のサマリー情報のみを必要とする場合、ReportQuery108.7.5項「レポート問合せ」を参照)を使用するとより効率的です。

詳細は、109.2.1.2項「部分オブジェクト問合せを使用したオブジェクトの読取り」を参照してください。

108.7.1.4 読取り専用問合せ

データが読取り専用であることがわかっている場合は、問合せを読取り専用として指定することでパフォーマンスを向上できます。これにより、問合せによって返されるオブジェクトが不変であることがTopLinkに通知されます。

詳細は、次を参照してください。

108.7.1.5結合読取りとオブジェクト・レベルの読取り問合せ

結合読取りは、クラスの単一問合せにより、そのクラスのインスタンスおよび関連オブジェクトのインスタンスを作成するデータが戻されるようにする、問合せ最適化機能です。この機能を使用し、データベース・アクセスを減少させることによって、問合せのパフォーマンスを向上できます。デフォルトでは、リレーションシップは結合読取りされません。すなわち、各リレーションシップは、インダイレクション(遅延ロード)を使用している場合はアクセス時に別々にフェッチされ、インダイレクションを使用していない場合はアクセス時に独立したデータベース問合せとしてフェッチされます。詳細は、17.2.4項「インダイレクション(遅延ロード)」を参照してください。

結合読取りをReadObjectQueryおよびReadAllQueryとともに使用して、表108-4に示すマップされたリレーションシップを結合できます。結合読取りは、その他のリレーションシップ・マッピングでは現在サポートされていません。

表108-4 マッピング・タイプ別の結合読取り

Query マッピング・タイプ

ReadObjectQuery

ReadAllQuery


結合読取りでは、複数のネステッド・リレーションシップを結合することを指定できます。ネステッド結合は、式(110.2.7項「結合リレーションシップと複雑なリレーションシップを表す式」を参照)を使用して表現されます。

外部結合も、式の外部結合APIを使用することで、結合読取りとともに使用できます。外部結合を使用していない場合、1対1のリレーションシップがないか1対多のリレーションシップが空のオブジェクトが、結果セットからフィルタ処理されます。また、継承先サブクラスを外部結合できるようにオブジェクト・レベルの読取り問合せを構成すると、クラスごとに問合せをする負荷を回避できます。表108-4に示されているいずれかのマッピングのuseInnerJoinFetchまたはuseOuterJoinFetchメソッドを使用して、内部結合または外部結合を指定することもできます。

結合読取りはカスタムのSQLまたはストアド・プロシージャで使用することができますが、問合せでは、すべての結合読取りオブジェクトを作成するために必要なデータがすべて戻されるようにする必要があります。結果セットに同じ表またはフィールドが複数含まれている場合は、これらが戻される順序は、TopLinkで生成される表順序と共通にする必要があります。

詳細は、次を参照してください。

108.7.1.5.1 結合読取りの重複データの代替策

1対多のリレーションシップまたは共有されている1対1のリレーションシップが結合される場合、結合読取りは、重複データを返すことがあります。TopLinkでは、オブジェクト結果内の重複結果を正しくフィルタ処理しますが、重複データは、依然としてデータベースからフェッチされてしまい、このため、特に複数の1対多のリレーションシップが結合されている場合には、パフォーマンスを低下させる可能性があります。一般的に、バッチ読取りは、結合読取りの代替として使用できますが、重複データをフェッチする必要がない点でより優れています。

1対多の結合は、多くの場合、スケーラビリティがよくないため、注意しながら使用することをお薦めします。

ReadObjectQueryの場合は、主な負荷はSQL実行にあるため、1対多の結合のパフォーマンスは、結合を使用しない問合せよりも通常高くなります。

これに対して、ReadAllObjectQueryの場合、主な負荷は行のフェッチであり、これはさらに結合の重複データにより増大するため、1対多の結合のパフォーマンスは、多くの場合に行うバッチ読取りよりも非効率になります(ただし、1対多の結合は、1つずつオブジェクトを読み取るよりは高効率です)。

これは、主に、1対多の結合では重複データが読み取られるためです。つまり、各ソース・オブジェクトのデータがターゲット・オブジェクトごとに重複化されるためです。これは、1対多リレーションシップのサイズとソース・オブジェクトの行のサイズによっては、非常に非効率的です。特に、ソース・オブジェクトにラージ・オブジェクト(LOB)がある場合は、そうです。

複数またはネストの1対多の結合を同一の問合せ内で使用する場合は、問題は複雑になります。ソース・オブジェクトの行はn*m回重複し、各ターゲット・オブジェクトはそれぞれn回およびm回重複します。これは、パフォーマンス上大きな問題となります。

空のコレクションを処理するには、外部結合を使用する必要があり、このため問合せを行うことによってデータベースに非常に負担をかけることになります。バッチ読取りには、必要なデータのみを返し、外部結合を行う必要がないという利点があります。

すべてのオブジェクトを読み取るアプリケーションにおいてリレーションシップの問合せを最適化するには、バッチ読取りを使用することをお薦めします。

詳細は、次を参照してください。

108.7.1.6 フェッチ・グループとオブジェクト・レベルの読取り問合せ

フェッチ・グループは、ReadObjectQueryまたはReadAllQueryとともに使用できます。問合せを実行すると、TopLinkによりフェッチ・グループ内の属性のみが取得されます。除外された属性のいずれかに関するgetterメソッドをコールすると、TopLinkでは、このサブセットから除外されたすべての属性をフェッチする問合せが自動的に実行されます。

詳細は、次を参照してください。

108.7.2 データ・レベルの読取り問合せ

DataLevelReadQueryを使用すると、データ・ソースに問い合せ、指定した選択基準に一致するObjectインスタンスを返すことができます。この項の内容は次のとおりです。

詳細は、109.2.4項「DatabaseQueryを使用したデータの読取り方法」を参照してください。


警告:

検証されていないSQL文字列をDataReadQueryDirectReadQueryおよびValueReadQueryのようなオブジェクトのコンストラクタに渡せるようにすると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


108.7.2.1 DataReadQuery

DataReadQueryを使用すると、結果セットを表すRecordオブジェクトのCollectionを返す選択SQL文字列を実行できます。

108.7.2.2 DirectReadQuery

DirectReadQueryを使用すると、結果セットを表す値のCollectionが戻されたデータから1列(フィールド)を読み取ることができます。

108.7.2.3 ValueReadQuery

ValueReadQueryを使用すると、単一データ値(1つのフィールド)を読み取ることができます。単一データ値が戻されます。または、行が戻されない場合は、nullが戻されます。

108.7.3 オブジェクト・レベルの変更問合せ

ObjectLevelModifyQueryを使用すると、データ・ソースに問い合せ、オブジェクトを作成、更新および削除できます。この項の内容は次のとおりです。

詳細は、109.2.2項「DatabaseQueryを使用したオブジェクトの作成、更新および削除方法」を参照してください。


注意:

オブジェクトは、TopLink UnitOfWorkを使用して作成および更新することをお薦めします。これがトランザクション、同時実行性および参照制約を管理する最も効率のよい方法です。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。

108.7.3.1 WriteObjectQuery

オブジェクトが新規かどうかわからない場合は、WriteObjectQueryを使用します。TopLinkでは、挿入または更新を実行するかどうかを判断する際に必要上、存在チェックを実行します。

オブジェクトが既存かどうかがわからない場合は、UpdateObjectQuery108.7.3.2項「UpdateObjectQuery」を参照)またはInsertObjectQuery108.7.3.3項「InsertObjectQuery」を参照)を使用することで存在チェックを回避できます。

108.7.3.2 UpdateObjectQuery

変更対象のオブジェクトが存在することがわかっている場合は、UpdateObjectQueryを使用して、TopLinkでの存在チェックを省略できます。

108.7.3.3 InsertObjectQuery

オブジェクトが新規であることがわかっている場合は、InsertObjectQueryを使用することで、TopLinkでの存在チェックを省略できます。

108.7.3.4 DeleteObjectQuery

引数として特定のオブジェクトを1つ持つDeleteObjectQueryを作成することで、特定のオブジェクトを削除できます。

108.7.3.5 UpdateAllQuery

UpdateAllQueryでは、式を使用して、オブジェクトをメモリーにロードせずに(オブジェクト・レベルで)オブジェクトのセットを更新できます。具体的な値の更新、または相対値での更新ができます。たとえば、値を5に設定したり、5%ずつ増分するように設定できます。

詳細は、109.2.3.1項「UpdateAllQueryの使用」を参照してください。

108.7.3.6 DeleteAllQuery

複数のオブジェクトを削除するには、DeleteAllQueryを作成し、そのsetObjectsメソッドを使用して、削除対象の特定のオブジェクトのコレクションを構成します。DeleteAllQueryのメソッドsetReferenceClassを使用して、削除対象のオブジェクトの参照クラスを構成します。指定された各オブジェクトが削除されますが、その私有部分は削除されません。

DeleteAllQueryの場合、1つのトランザクションですべての削除が実行されます。

詳細は、109.2.3.2項「DeleteAll問合せの使用」を参照してください。

108.7.3.7 オブジェクト・レベルの変更問合せと私有部分

オブジェクトの作成または更新のDatabaseQueryを実行すると、デフォルトではオブジェクトとその私有部分の両方がデータベースに書き込まれます。私有部分を更新しない問合せを作成するには、DatabaseQueryのメソッドdontCascadePartsを使用します。このメソッドは、次の目的で使用します。

  • オブジェクトのダイレクト属性のみが変更されたことがわかっている場合に、パフォーマンスを向上させること。

  • 独立した新規オブジェクトの大きなグループを作成する場合に、参照整合性の依存関係を自分で解決すること。


    注意:

    作業ユニットでは参照整合性が内部的に解決されるため、作業ユニットを使用してデータ・ソースに書き込む場合はこのメソッドは不要です。詳細は、第113章「TopLinkトランザクションの概要」を参照してください。

108.7.4 データ・レベルの変更問合せ

DataModifyQueryを使用すると、データ・ソースに問い合せ、選択を行わないSQL文を実行できます。これは、SessionのメソッドexecuteNonSelectingCallと同等です。

詳細は、109.2.5項「DatabaseQueryを使用したデータの更新方法」を参照してください。

108.7.5 レポート問合せ

オブジェクトのセットの、特定の属性を要約(または集計)する場合、ReportQueryを使用できます。

ReportQueryは、オブジェクトのセットおよび関連オブジェクトを基にサマリー・データを戻します。つまり、オブジェクトに関するデータを戻します。また、複数のオブジェクトを戻すこともできます。ReportQueryでは、オブジェクト・レベルでのデータの問合せおよび指定ができます。レポート問合せを作成するには、検索基準、含める必要のあるオブジェクト情報およびデータの要約方法を指定します。

たとえば、社内の全従業員の平均年齢を計算するレポート問合せを作成できます。このレポート問合せの対象となるのは特定のオブジェクト(従業員)ではなく、オブジェクトに関するサマリー情報(従業員の平均年齢)です。

ReportQueryは、次の目的で使用します。

  • オブジェクトの属性とその関連オブジェクトの属性のサブセットを指定すること。これにより、軽量の情報の問合せが可能になります。

  • 選択基準と順序付けの基準を表す、オブジェクトレベルの複雑な式を作成すること。

  • SUMMINMAXAVGCOUNTなど、(プラットフォームでサポートされている)データ・ソース集計関数を使用すること。

  • 式を使用してデータをグループ化すること。

  • ReportQueryResultで主キー属性を要求すること。これにより、軽量の結果から実際のオブジェクトを簡単に要求できるようになります。

ReportQueryは、データ・ソースのレポート機能(存在する場合)を利用できるため、最も効率的な形態の部分オブジェクト問合せ(108.7.1.3項「部分オブジェクト問合せ」を参照)です。部分オブジェクト問合せを実行する場合にはReportQueryを使用することをお薦めします。

ReportQuery APIは、ReportQueryResultオブジェクトのコレクションを返します。このオブジェクトは、構造と動作の点でRecordMapに似ています。詳細は、108.5.2項「レポート問合せの結果」を参照してください。

詳細は、次を参照してください。

108.8名前付き問合せ

readAllObjectsのようなセッション問合せメソッド(108.6項「セッション問合せ」を参照)を使用すると、TopLinkでは、そのタスクを実行するために必要なその他のオブジェクトを作成する、対応するReadAllQueryを作成します。readAllObjectsメソッドの実行が終了すると、これらのオブジェクトは破棄されます。このセッション・メソッドをコールするたびに、これらの関連オブジェクトが再作成され、一度使用された後、破棄されます。

または、DatabaseQuery108.7項「データベース問合せ」を参照)は、作成後に、ディスクリプタ・レベル(119.7項「ディスクリプタ・レベルでの名前付き問合せの構成」を参照)またはセッション・レベル(89.13項「セッション・レベルでの名前付き問合せの構成」を参照)で名前付きで保存することもできます。

TopLinkでは、名前付き問合せは1回のみプリコンパイルされ、以後、名前付き問合せ(とその基礎となるすべての関連オブジェクト)は、効率的に再利用でき、頻繁に実行する操作に適用できます。

セッションAPI(109.3項「名前付き問合せの使用」を参照)を使用すると、これらの名前付き問合せを必要な引数付きで実行できます。

名前付き問合せを使用する方がよい場合

頻繁に実行するかなり複雑な問合せの場合は、問合せを名前付き問合せにすることを検討してください。

問合せがプロジェクトにおいてグローバルな場合は、名前付き問合せをセッション・レベル(89.13項「セッション・レベルでの名前付き問合せの構成」を参照)に構成します。

問合せがClassにおいてグローバルな場合、またはCMPファインダを構成する場合は、名前付き問合せをディスクリプタ・レベル(119.7項「ディスクリプタ・レベルでの名前付き問合せの構成」を参照)に構成します。ディスクリプタ・レベルでの問合せの構成の詳細は、108.13項「ディスクリプタ問合せマネージャ問合せ」を参照してください。

問合せが非常に複雑な場合は、リダイレクト問合せという特別な形式の名前付き問合せを使用して、独自のstaticメソッドに問合せの実行を委譲できます。リダイレクト問合せの詳細は、108.10項「リダイレクト問合せ」を参照してください。

名前付き問合せを使用しない方がよい場合

まれにしか使用されない問合せは、必要に応じて作成する方が効率的です。特定の問合せをほとんど使用しない場合、セッションの起動時にその問合せを作成して格納するだけの価値がないこともあります。

108.9 コール問合せ

すべてのセッション・タイプでは、次のいずれかのCallタイプを取るexecuteSelectingCallおよびexecuteNonSelectingCallメソッドを使用できます。

Callは、DatabaseQueryのコンテキストで実行することもできます。DatabaseQueryの詳細は、108.7項「データベース問合せ」を参照してください。


警告:

検証されていないSQL文字列をメソッド(たとえばexecuteSelectingCall(String sql)メソッド)に渡せるようにすると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


108.9.1 SQLコール

SQLコールでは、リレーショナル・データベースのフィールドにアクセスします。TopLinkでは、次のSQLコールがサポートされています。

Call API(またはSQL文字列表記規則)を使用すると、入力、出力および入出力パラメータを指定でき、入力および入出力パラメータに値を割り当てることができます。

ディスクリプタReturningPolicyを使用すると、TopLinkでパラメータに書き込むか、データベースによって生成された値を取得するか、またはその両方を行うかを制御できます。詳細は、119.27項「リターン・ポリシーの構成」を参照してください。

108.9.1.1 SQLCall

SQLCallを使用すると、任意のSQL文を指定して、データ・ソースでそれを実行できます。


警告:

検証されていないSQL文字列をメソッドに渡せるようにすると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


詳細は、109.4項「SQLCallの使用」を参照してください。

108.9.1.2 StoredProcedureCall

ストアド・プロシージャは、複数の手続き型言語(Procedural Language/Structured Query Language(PL/SQL)など)で構成され、データベースに名前付きで保存されます。ほとんどのリレーショナル・データベースが、ストアド・プロシージャをサポートします。

ストアド・プロシージャを起動すると、ロジックを実行してデータ・ソースからデータにアクセスできます。

StoredProcedureCallでは、実行エラーの検出と、入力パラメータ、出力パラメータおよび入出力パラメータの指定ができます。ただし、ストアド・プロシージャでは戻り値を返しません。

詳細は、109.5項「StoredProcedureCallの使用」を参照してください。

108.9.1.3 StoredFunctionCall

ストアド・ファンクションは、ストアド・プロシージャのすべての機能のみでなく、値を返す機能も提供するOracleデータベースの機能です。

StoredFunctionCallでは、StoredProcedureCallのすべての機能のみでなく、戻り値のフィールド名を指定できます。

詳細は、109.6項「StoredFunctionCallの使用」を参照してください。

108.9.2 EJB QLコール

TopLinkでは、EJB QLコールは、EJB QL文字列を表します。EJBQLCallオブジェクトは、データベース起動の抽象オブジェクトです。EJB QLコールは、セッションから直接実行することも、あるいはDatabaseQueryのコンテキストで実行することもできます。

詳細は、次を参照してください。

108.9.3 企業情報システム(EIS)インタラクション

Java EE Connector Architecture(JCA)アダプタを介してリモートEISに対する問合せを起動するには、CallのインスタンスであるEISInteractionを使用します。TopLinkでは、次のEISInteractionタイプがサポートされています。

これらの各インタラクションには、EISに対して起動する関数を識別する関数インタフェース(ストアド・プロシージャに類似)を指定します。この関数インタフェースには次のものがあります。

  • 関数名

  • レコード名(関数名と異なる場合)

  • 入力引数のリスト

  • 出力引数のリスト

詳細は、次を参照してください。

108.9.3.1 IndexedInteraction

IndexedInteractionでは、索引付きレコードを使用して、データをEISと交換します。引数の指定順序は、索引付きレコードに定義されている値の順序と一致している必要があります。

108.9.3.2 MappedInteraction

MappedInteractionでは、マップ済レコードを使用して、データをEISと交換します。指定する引数は、名前によって、マップ済レコードのフィールドにマップされます。

108.9.3.3 XMLInteraction

XMLInteractionは、MappedInteractionに、データをXMLレコードにマップする機能を追加したものです。XMLInteractionの場合、オプションでルート要素名を指定することもできます。

108.9.3.4 XQueryInteraction

JCAアダプタがXQuery動的問合せ言語をサポートする場合には、XQueryInteractionを使用できます。これは、XQuery文字列を指定できるようにしたXMLInteractionです。

108.9.3.5 QueryStringInteraction

JCAアダプタが問合せ文字列ベースの動的問合せ言語をサポートする場合には、QueryStringInteractionを使用できます。これは、MappedInteractionに、動的問合せ文字列を指定する機能を追加したものです。

108.10 リダイレクト問合せ

複雑な問合せロジックに対応するために、リダイレクト問合せを実装できます。これは名前付き問合せで、問合せの実行制御をアプリケーションに委譲します。詳細は、108.8項「名前付き問合せ」を参照してください。

リダイレクト問合せを使用すると、問合せの実装をstaticメソッドとしてコードで定義できます。問合せを起動したときには、コールは指定したstaticメソッドにリダイレクトされます。リダイレクト問合せは、Vectorにパッケージ化された形で自身に渡されるパラメータをすべて受け入れます。

TopLink問合せのほとんどはオブジェクトを直接検索しますが、リダイレクト問合せは一般的に、別のクラスのメソッドを起動して結果を待ちます。リダイレクト問合せを使用すると、複雑な操作(他の方法では問合せフレームワーク内で実行できない操作を含む)を作成して使用することができます。

リダイレクト問合せを使用すると、問合せの起動がユーザーの提供するメソッドに委譲されるため、問合せを引数の値に基づいてどのように実行するのかを動的に決定できます。

リダイレクト問合せを使用すると、次のことが可能になります。

UnitOfWorkで問合せを実行する場合、結果はUnitOfWorkのインスタンスに登録されるため、起動メソッドで取得するのはセッション・キャッシュ内のオブジェクトである必要があります。

リダイレクト問合せを作成するには、QueryRedirectorインタフェースを実装し、この実装を名前付き問合せに設定します。

TopLinkに付属するQueryRedirectorのインスタンスであるMethodBasedQueryRedirectorを利用することをお薦めします。これは、staticメソッドの名前および、このメソッドがパラメータとして定義されているClassを引数として取ります。名前付き問合せにMethodBasedQueryRedirectorを設定した場合、このインスタンスのinvokeQueryメソッドをコールするたびに、TopLinkでは、staticメソッドを起動するためにリフレクションをかわりに使用します。

MethodBasedQueryRedirectorを使用する利点は、次のとおりです。

詳細は、111.1項「リダイレクト問合せの使用」を参照してください。

108.11 履歴問合せ

デフォルトでは、セッションはオブジェクトの最新バージョンの表示を表し、そのセッションで問合せを実行すると、選択したオブジェクトの最新バージョンが戻されます。

データ・ソースが過去バージョンすなわち履歴バージョンのオブジェクトを保持している場合は、この履歴データにアクセスするようにTopLinkを構成できます(87.6項「履歴セッション」を参照)。

履歴データを利用するようにTopLinkを構成すると、表108-5にまとめた履歴問合せを使用して履歴バージョンにアクセスできます。


注意:

フラッシュバック問合せは、ビュー選択をサポートしません。つまり、全サブクラス読取り用のビューの継承ポリシーを持つオブジェクトに対して、フラッシュバック問合せは使用できません。詳細は、16.3項「ディスクリプタと継承」を参照してください。

表108-5 履歴問合せ

履歴問合せのタイプ セッション キャッシュ maintainCacheをfalseに設定する必要があるか 現在のバージョンと履歴バージョンの両方についての問合せ

AsOfClauseを持つObjectLevelReadQueryの使用


標準脚注1

  • グローバル

  • 読取り専用

  • 現在のバージョンが含まれる

×

式演算子asOfを持つObjectLevelReadQueryの使用


標準脚注1

  • グローバル

  • 読取りと書込み

  • 現在のバージョンが含まれる

×

履歴セッションでのObjectLevelReadQueryの使用


履歴脚注2

  • 独立

  • 読取り専用

  • 指定された時刻現在に存在する静的スナップショットが含まれる

×

×


脚注1 Oracle9i以降のOraclePlatformまたはTopLink HistoryPolicyを使用したサーバーまたはデータベースのセッション。

脚注2 OraclePlatformまたはTopLink HistoryPolicyを使用したサーバーまたはデータベースのセッションにより、AsOfClause付きのacquireHistoricalSessionメソッドを使用して返されたセッション。

108.11.1 AsOfClauseを持つObjectLevelReadQueryの使用

ObjectLevelReadQueryのメソッドsetAsOfClauseで設定したAsOfClauseObjectLevelReadQueryを構成することで、オブジェクトの履歴バージョンを問い合せることができます。AsOfClauseには、問合せで使用するすべてのExpressionに適用される時刻を指定します。

このタイプの履歴問合せを使用すると、指定された時刻現在で存在する各オブジェクト・バージョンの静的スナップショットについて問い合せることができます。


注意:

オブジェクトの古いバージョンを持つグローバル共有キャッシュが破損することを回避するには、この履歴問合せでObjectLevelReadQueryのメソッドmaintainCachefalseに設定する必要があります。設定しない場合は、問合せを実行する際に、TopLinkにより例外がスローされます。

AsOfClauseを持つObjectLevelReadQueryの使用方法の詳細および例は、111.2項「履歴問合せの使用」を参照してください。

108.11.2 式演算子asOfを持つObjectLevelReadQueryの使用

ObjectLevelReadQueryReadObjectQueryまたはReadAllQueryなど)を使用して、オブジェクトの履歴バージョンについて問い合せることができます。ObjectLevelReadQueryには、Expression演算子asOfを使用する1つ以上の式を指定し、Expressionごとに時刻を指定します。

このタイプの履歴問合せを使用すると、オブジェクトの現在のバージョンと履歴バージョンの両方を同じ問合せ内で組み合せることができます。

AsOfClauseを持つObjectLevelReadQueryを構成する際には、AsOfClauseに指定した時刻により、問合せの各Expressionに指定した時刻がオーバーライドされます(108.11.1項「AsOfClauseを持つObjectLevelReadQueryの使用」を参照)。

Expressionの演算子asOfを持つObjectLevelReadQueryの使用方法の詳細および例は、111.2項「履歴問合せの使用」を参照してください。

108.11.3 履歴セッションでのObjectLevelReadQueryの使用

セッションが(該当するOraclePlatformまたはTopLink HistoryPolicyに基づく)オブジェクトの履歴バージョンを保持する場合は、SessionのメソッドacquireHistoricalSessionAsOfClauseを渡します。AsOfClauseには、すべての問合せと式に適用する時刻を指定します。

このメソッドにより、指定された時刻現在で存在する各オブジェクト・バージョンの、読取り専用の軽量なスナップショットが返されます。このタイプのセッションで使用されるキャッシュは、グローバル共有キャッシュからは独立しています。このため、ObjectLevelReadQueryのメソッドmaintainCachefalseに設定する必要はありません。

履歴セッションを持つObjectLevelReadQueryの使用方法の詳細および例は、111.2項「履歴問合せの使用」を参照してください。

108.12 インタフェースと継承問合せ

インタフェース・ディスクリプタ(22.2.1.3項「リレーショナル・インタフェース・ディスクリプタの作成」を参照)を定義すると、インタフェースおよび継承階層に対する問合せを実行できます。

詳細は、次を参照してください。

108.13 ディスクリプタ問合せマネージャ問合せ

DescriptorDescriptorQueryManagerのインスタンスを所有しており、このインスタンスは次の目的に使用できます。

108.13.1 名前付き問合せの構成方法

DescriptorQueryManagerには、頻繁に使用する名前付き問合せを保存および取得するためのAPIが用意されています。

詳細は、108.8項「名前付き問合せ」を参照してください。

108.13.2 デフォルトの問合せ実装の構成方法

DescriptorDescriptorQueryManagerでは、TopLinkが次のデータ・ソース操作に使用する問合せの実装をカスタマイズできます。

  • オブジェクトの挿入

  • オブジェクトの更新

  • オブジェクトの読取り

  • すべてのオブジェクトの読取り

  • オブジェクトの削除

たとえば、ストアド・プロシージャを使用してオブジェクトを挿入する必要がある場合、DescriptorQueryManagerのオブジェクト挿入問合せで使用されるデフォルトのSQLCallをオーバーライドできます。

任意のClassに対する問合せを実行すると、TopLinkでは、DescriptorQueryManagerを参照して、指定のデータ・ソース操作を実行する方法が決定されます。

この機能の用途は、TopLink動作の拡張、非リレーショナル・データへのアクセスまたはストアド・プロシージャやカスタマイズされたSQLコールの使用など、様々です。


警告:

検証されていないSQL文字列をメソッドに渡せるようにすると、SQLインジェクション攻撃に対してアプリケーションが脆弱になります。


これらのデフォルトの問合せ実装のカスタマイズ方法の詳細と例は、次を参照してください。

108.13.3 追加の結合式の構成方法

あるクラスで実行する各問合せに自動的に式を追加するよう、DescriptorQueryManagerを構成することができます。たとえば、特定のクラスの有効なインスタンスに対してデータ・ソースをフィルタ処理する式を追加できます。

詳細は、111.7項「その他の結合式の追加」を参照してください。

108.14 Oracle拡張機能

TopLinkをOracleデータベースとともに使用する場合は、TopLinkアプリケーション内から次のOracle固有の問合せ機能を使用できます。

108.14.1 ヒント

Oracleでは、データベース・サーバーのSQLオプティマイザの動作を変更できる、ヒントというSQL問合せの追加機能を指定できます。これを使用すると、通常オプティマイザで行われる設定を変更できます。ヒントを使用して、結合文の結合順序やSQLコールの最適化方法などを指定します。

ヒントを指定するには、DatabaseQueryのメソッドsetHintStringを使用します。

詳細は、次を参照してください。

108.14.2 階層問合せ

Oracleデータベースの階層問合せメカニズムを使用すると、階層順序に基づいてデータベースの行を選択できます。たとえば、特定の従業員の行、その従業員が管理する人々の行、その人々に管理される従業員の行などの順序で読取りを行う問合せを設計できます。

DatabaseQueryのサブクラスReadAllQueryのメソッドsetHierarchicalQueryClauseを使用して、階層問合せ句を指定します。DatabaseQuery問合せの詳細は、108.7項「データベース問合せ」を参照してください。

Oracle階層問合せ句でのReadAllQueryの構成の詳細は、111.9.2項「階層問合せの使用方法」を参照してください。

108.14.3 フラッシュバック問合せ

TopLinkをOracle9iデータベース以降とともに使用する場合、特別な履歴セッションを取得できます。このセッションでは、過去の特定時刻までのすべてのオブジェクトが読み取られ、ある期間にどのようにオブジェクトが変更されているかについての条件を付けた読込み問合せを表現できます。

詳細は、108.11項「履歴問合せ」を参照してください。

108.14.4 ストアド・ファンクション

ストアド・ファンクションは、ストアド・プロシージャのすべての機能を提供するのみでなく値も返せるOracleデータベースのメカニズムです。

詳細は、108.9.1.3項「StoredFunctionCall」を参照してください。

108.15 EJB 2.n CMPファインダ

EJBファインダとは、EJB仕様によって定義された問合せです。EJBファインダは、EJB、コレクションおよび列挙値を戻します。ファインダと問合せの違いは、問合せがJavaオブジェクトを返すのに対し、ファインダはEJBを返す点です。TopLink問合せフレームワークでは、エンティティBeanを取得する複雑なファインダを作成して実行できます。

ファインダには、検索基準を定義するファインダ・メソッドが含まれています。ファインダ・メソッドの作成に必要な作業は、コンテナ管理の永続性(CMP)によるBeanファインダを作成するのか、Bean管理の永続性(BMP)によるBeanファインダを作成するのかによって異なります。

どちらの場合も、ファインダはBeanのHomeインタフェースで定義します。

任意のTopLink問合せ機能を使用してファインダを実装できます。また、CMPおよびBMPエンティティBeanのためにTopLinkに用意されている事前定義ファインダの実装を利用できます。

この項の内容は次のとおりです。

詳細は、111.10項「EJB 2.n CMPファインダの使用」を参照してください。

108.15.1 事前定義ファインダ

TopLinkでは、豊富なAPIが用意された事前定義ファインダが実装されています。このAPIを使用すると、実行時に問合せプロパティを動的に指定でき、TopLink問合せ機能を完全に活用できるようになります。

TopLinkでは、次の事前定義ファインダが用意されています。

詳細は、次を参照してください。

108.15.1.1 事前定義CMPファインダ

表108-6は、TopLink CMP(OC4Jを使用)で使用できる事前定義ファインダを示します。

表108-6にリストしたメソッド名は、TopLinkランタイムで予約されています。

表108-6 事前定義CMPファインダ

メソッド 引数 戻りタイプ

findAll

()

Collection

findManyByEJBQL

(String ejbql) (String ejbql, Vector arguments)

Collection

findManyByQuery

(DatabaseQuery query)(DatabaseQuery query, Vector arguments)

Collection

findManyBySQL

(String sql)(String sql, Vector arguments)

Collection

findByPrimaryKey

(Object primaryKeyObject)

EJBObject

findOneByEJBQL

(String ejbql) (String ejbql, Vector arguments)

EJBObject

findOneByQuery

(DatabaseQuery query)(DatabaseQuery query, Vector arguments)

EJBObject

findOneBySQL

(String sql)(String sql, Vector arguments)

EJBObject



注意:

ファインダがローカル・ホームに位置している場合、findOneByが含まれているファインダのEJBObjectEJBLocalObjectに置き換えます。

これらのファインダは、それぞれ引数のVectorなしで使用することもできます。たとえば、EJBObject findOneByEJBQL(String ejbql)は有効な動的ファインダですが、EJBObjectの戻りタイプをBeanのコンポーネント・インタフェースに置き換える必要があります。

詳細は、111.10項「EJB 2.n CMPファインダの使用」を参照してください。

108.15.1.2 事前定義BMPファインダ

表108-7は、oracle.toplink.ejb.bmp.BMPEntityBase2.15項「BMPを使用するEJBエンティティBeanのアーキテクチャについて」を参照)を基にBMP EJBを拡張する場合に使用できる事前定義ファインダを示します。

表108-7にリストしたメソッド名は、TopLinkランタイムで予約されています。

表108-7 事前定義BMPファインダ

メソッド 引数 戻りタイプ

findAll

()(Call)(Expression)(ReadAllQuery)

Enumeration

findAllByNamedQuery

(String queryName, Vector arguments)

Enumeration

findByPrimaryKey

(Object primaryKeyObject)

Object

findOne

(Call) (Expression) (ReadObjectQuery)

Object

findOneByNamedQuery

(String queryName, Vector arguments)

Object


EJBファインダの使用方法の詳細は、111.10項「EJB 2.n CMPファインダの使用」を参照してください。

108.15.2 デフォルト・ファインダ

findBy<CMP-FIELD-NAME><CMP-FIELD-NAME>はBeanの永続フィールド名)という名前のエンティティBeanのホーム・インタフェースに定義された各ファインダ・メソッドに対して、TopLinkにより、ファインダの実装(TopLinkの式フレームワークを使用したTopLink問合せを含む)が生成されます。戻りタイプが単一のBeanタイプの場合は、TopLinkではReadObjectQueryが作成されます。戻りタイプがCollectionの場合は、TopLinkではReadAllQueryが作成されます。

エンティティのホームでのファインダの定義が必要なことは変わりませんが、ejb-jar.xmlファイルでファインダを宣言する必要がなくなります。

詳細は、111.10.1項「ファインダの作成方法」を参照してください。

108.15.3 コール・ファインダ

Callを使用するファインダを使用すると、デプロイ時ではなく実行時に生成する動的問合せを作成できます。

詳細は、次を参照してください。

108.15.4 DatabaseQueryファインダ

DatabaseQueryを使用するファインダを使用すると、デプロイ時ではなく実行時に生成する動的問合せを作成できます。

TopLinkには、DatabaseQueryをとるファインダに加えて、特定のタイプのEJBをすべて返すデフォルトのfindAllファインダも用意されています。他の動的ファインダと同様に、findAllという名前もTopLinkランタイムで予約されています。

詳細は、108.7項「データベース問合せ」を参照してください。

DatabaseQueryをとるTopLink事前定義ファインダの詳細は、108.15.1項「事前定義ファインダ」を参照してください。

108.15.5 名前付き問合せファインダ

DescriptorQueryManagerまたはSessionに保存された名前付きDatabaseQueryを使用するファインダを使用すると、頻繁に実行する問合せを効率的に再利用できます。

詳細は、次を参照してください。

108.15.6 主キー・ファインダ

TopLinkでは、Java Objectの主キー・クラスをとる事前定義ファインダを実装しています。

EJB 2.0および2.1の仕様により、コンテナは各BeanのHomeインタフェースでfindByPrimaryKeyコールを実装する必要があるため、このファインダをBeanから削除しないでください。

詳細は、108.15.1項「事前定義ファインダ」を参照してください。

108.15.7 式ファインダ

TopLinkのExpressionを使用したファインダを使用すると、次のような利点があります。

  • Javaコードでの標準的な問合せがバージョン制御可能

  • 複雑な操作のほとんどを単純化可能

  • EJB QLの場合よりも充実した問合せ機能

式を使用すると、オブジェクト・モデルに基づいてファインダの検索基準を指定できるため、多くの場合、式はファインダの構成に最も適した方法です。

詳細は、108.2.6項「TopLinkの式」を参照してください。

ExpressionをとるTopLink事前定義ファインダの詳細は、108.15.1項「事前定義ファインダ」を参照してください。

DatabaseQueryのメソッドsetSelectionCriteriaを使用することで、DatabaseQueryをとるファインダでもExpressionを使用できます。DatabaseQueryをとるTopLink事前定義ファインダの詳細は、108.15.4項「DatabaseQueryファインダ」を参照してください。

108.15.8 EJB QLファインダ

TopLinkでは、EJB QLがサポートされています。EJB QLファインダを使用すると、EJB QL文字列を問合せの実装として指定できます。

EJB QLには次のような利点があります。

  • 問合せのEJB 2.0および2.1標準です。

  • ほとんどの問合せの構成に使用できます。

  • EJB QLを使用すると、依存オブジェクト問合せを実装できます。

EJB QLの短所は、複雑な問合せを構成する場合に使用方法が難しいことです。

TopLinkにおけるEJB QLのサポートの詳細は、108.2.8項「問合せ言語」を参照してください。

EJB QLをとるTopLink事前定義ファインダの詳細は、108.15.1項「事前定義ファインダ」を参照してください。

108.15.9 SQLファインダ

SQLを使用してファインダを定義すると、次のような利点が得られます。

  • EJB QLやTopLinkのExpressionを使用したときには表現できないロジックを実装できます。

  • TopLinkで生成されたSQLのかわりに、ストアド・プロシージャを使用できます。

  • カスタムSQLによってパフォーマンスが向上する場合があります。

SQLファインダには次のような短所もあります。

  • 複雑なカスタムSQL文を記述すると、データベースの表が変更された場合に、大幅なメンテナンス作業が必要になります。

  • SQLをハード・コードすると、他のデータベースへの移植性が制限されます。

  • SQL文字列に対する検証が行われません。SQL文のエラーは、実行時まで検出されません。

  • SELECT以外の関数にSQLを使用すると、予測できないエラーが発生する可能性があります。

SQLをとるTopLink事前定義ファインダの詳細は、108.15.1項「事前定義ファインダ」を参照してください。

108.15.10 リダイレクト・ファインダ

リダイレクト・ファインダを使用すると、任意のヘルパー・クラスでstaticメソッドとして定義されるファインダを実装できます。ファインダを起動したときには、コールは指定したstaticメソッドにリダイレクトされます。

リダイレクト問合せは複雑であり、問合せを定義するための余分なヘルパー・メソッドも必要になります。しかし、リダイレクト問合せは複雑なロジックをサポートしているため、実装する必要のあるロジックが、リダイレクト・メソッドがコールされるBeanに関連していない場合には、しばしば最適な方法となります。

詳細は、次を参照してください。

108.15.11 ejbSelectメソッド

ejbSelectメソッドとは、エンティティBeanインスタンスで内部的に使用することを目的とした問合せメソッドです。抽象Bean自体に指定されるejbSelectメソッドは、ホームまたはコンポーネント・インタフェースでクライアントに直接公開されることはありません。各Beanは抽象として定義され、このようなメソッドを0個以上含むことができます。

ejbSelectメソッドには次の特性があります。

  • メソッド名に接頭辞としてejbSelectを付ける必要があります。

  • publicとして宣言する必要があります。

  • abstractとして宣言する必要があります。

  • throws句にはjavax.ejb.FinderExceptionを指定する必要がありますが、アプリケーション固有の例外も指定できます。

  • ejb-jar.xmlファイルのresult-type-mappingタグによってejbSelectメソッドの戻りタイプが決まります。このフラグをRemoteに設定するとEJBObjectsが返され、Localに設定するとEJBLocalObjectsが返されます。

ejbSelectメソッド定義の書式は次のようになります。

public abstract type ejbSelect<METHOD>(...);

ejbSelect問合せの戻りタイプは、ejbSelectが起動されるエンティティBeanのタイプに限定されません。かわりに、コンテナ管理のリレーションシップまたはコンテナ管理のフィールドに対応する任意のタイプを返すことができます。ただし、次の例外を伴います。ejbSelectメソッドの戻りタイプがjava.util.Collectionの場合、その結果はセレクタが定義されたエンティティ・タイプである必要があります。

選択メソッドは、それが起動されるエンティティBeanインスタンスのアイデンティティに基づいていませんが、エンティティBeanの主キーを引数として使用できます。その場合、有効範囲を特定のエンティティBeanインスタンスに論理的に設定した問合せが作成されます。

ejbSelectメソッドでのTopLink問合せの使用方法の詳細は、111.10項「EJB 2.n CMPファインダの使用」を参照してください。

108.16問合せとキャッシュ

問合せを実行すると、データベースまたはTopLinkのセッション・キャッシュから情報が取得されます。問合せがTopLinkのキャッシュを使用する問合せ方法を構成して、パフォーマンスを最適化することができます。

TopLinkでは、クライアント側のキャッシュを維持し、データベースからの読取り操作が必要になる回数を減らしています。TopLinkでは、データベースに書き込まれたオブジェクトとデータベースから読み取られたオブジェクトをキャッシュし、オブジェクト・アイデンティティを維持します。問合せでキャッシュとデータベースがチェックされる順序は、問合せのパフォーマンスに影響を与えます。デフォルトでは、主キー問合せはデータベースにアクセスする前にキャッシュをチェックします。また、すべての問合せが行からオブジェクトを再作成する前にキャッシュをチェックします。


注意:

TopLinkディスクリプタのキャッシュ・ポリシー構成情報でデフォルトの動作をオーバーライドできます。詳細は、102.2.4項「明示的な問合せのリフレッシュ」を参照してください。

この項では、問合せとキャッシュの間のリレーションシップを操作する方法について説明します。この項の内容は次のとおりです。

108.16.1 キャッシュの構成方法

TopLinkアプリケーションのキャッシュには、すでにデータベースから読み取られたオブジェクト、またはデータベースに書き込まれたオブジェクトが保持されます。TopLinkアプリケーションでキャッシュを使用することにより、データベースへのアクセス回数が減少します。データベースへのアクセスには時間がかかり、リソースを消費するため、効果的なキャッシュ方法はアプリケーションを効率化する上で重要です。

キャッシュの構成と使用の詳細は、第102章「キャッシュの概要」を参照してください。

108.16.2 インメモリー問合せの使用方法

インメモリー問合せは、共有セッション・キャッシュに対して実行される問合せです。インメモリー問合せの構成を注意して行うとパフォーマンスが向上しますが、すべての問合せでインメモリー問合せが効果を発揮するわけではありません。たとえば、主キーを使用した個別オブジェクトの問合せの場合は、通常はインメモリー問合せを使用することでパフォーマンスが向上しますが、主キーを使用しない問合せの場合は向上する可能性が低くなります。デフォルトでは、主キーを使用してシングル・オブジェクトを検索する問合せでは、必要なオブジェクトをまずキャッシュから取得し、オブジェクトがキャッシュに存在しない場合はデータベースで検索を行います。その他すべての問合せタイプの場合は、デフォルトでデータベースを最初に検索します。特定の問合せをインメモリー・キャッシュまたはデータベース、あるいはその両方に対して実行するよう指定できます。インメモリー問合せを使用すると、問合せをデータベースではなくキャッシュに対して実行することができます。


注意:

インメモリー問合せから順序付けされた結果は得られません。順序付けはインメモリー問合せではサポートされていないためです。

インメモリー問合せは次のリレーションシップをサポートします。

  • 1対1

  • 1対多

  • 多対多

  • 集約コレクション

  • ダイレクト・コレクション


    注意:

    デフォルトでは、リレーションシップ自体がメモリー内に存在しないと、インメモリー走査は行われません。必ずすべてのValueHolderをトリガーし、インメモリー問合せがリレーションシップ全体で機能するようにしてください。

この項の内容は次のとおりです。

108.16.2.1インメモリー問合せでのキャッシュ使用の構成

ReadObjectQueryメソッドとReadAllQueryメソッドを使用して、問合せレベルで、インメモリー問合せでのキャッシュの使用方法を構成できます。

  • checkCacheByPrimaryKey: デフォルトの設定です。読取り問合せに少なくとも主キーを比較する式が含まれている場合、メモリー内のオブジェクトに対して式を処理すると、キャッシュ・ヒットを取得できます。

  • checkCacheByExactPrimaryKey: 読取り問合せに主キーのみを比較する式が含まれている場合、メモリー内のオブジェクトに対して式を処理すると、キャッシュ・ヒットを取得できます。

  • checkCacheThenDatabase: 任意の読取り問合せを構成し、データベースにアクセスする前にキャッシュを完全にチェックすることができます。

  • checkCacheOnly: 任意のすべて読取り問合せを構成し、(作業ユニットのキャッシュではなく)親セッション・キャッシュのみをチェックして、データベースにアクセスせずに親セッション・キャッシュから結果を返すことができます。

  • conformResultsInUnitOfWork: 任意の読取り問合せまたはすべて読取り問合せを作業ユニットのコンテキスト内で構成し、作業ユニット内でオブジェクトに加えられた変更に結果を一致させることができます。これには、新規オブジェクト、削除されたオブジェクト、および変更されたオブジェクトが含まれます。一致させるときの制限の詳細は、115.4項「一致する問合せおよびディスクリプタの使用」を参照してください。

または、ObjectLevelReadQueryのメソッドsetCacheUsageを使用して該当するObjectLevelReadQueryフィールドを渡すことで、キャッシュの使用方法を構成できます。ObjectLevelReadQueryフィールドには、CheckCacheByPrimaryKeyCheckCacheByExactPrimaryKeyCheckCacheThenDatabaseCheckCacheOnlyConformResultsInUnitOfWorkまたはDoNotCheckCacheがあります。

108.16.2.2 インメモリー問合せでの式オプション

インメモリー問合せでは、Expressionメソッド(表108-8を参照)とExpressionMathメソッド(表108-9を参照)のサブセットを使用できます。これらのオプションの詳細は、第110章「TopLinkの式の概要」を参照してください。

表108-8 式演算子でのインメモリー問合せのサポート

式演算子 インメモリー問合せのサポート

addMonths

サポートされていない


and

サポートされている


anyof脚注1

サポートされている


anyofAllowingNone脚注1

サポートされている


asciiValue

サポートされていない


between

サポートされている


concat

サポートされている


currentDate

サポートされていない


dateToString

サポートされていない


decode

サポートされていない


equal

サポートされている


get脚注1

サポートされている


getAllowingNull脚注1

サポートされている


getFunction

サポートされていない


greaterThan

サポートされている


greaterThanEqual

サポートされている


hexToRaw

サポートされていない


ifNull

サポートされていない


in

サポートされている


isNull

サポートされている


lastDay

サポートされていない


leftPad

サポートされていない


leftTrim

サポートされていない


length

サポートされている


lessThan

サポートされている


lessThanEqual

サポートされている


like

サポートされている


monthsBetween

サポートされていない


newTime

サポートされていない


nextDay

サポートされていない


notBetween

サポートされている


notIn

サポートされている


notNull

サポートされている


or

サポートされている


ref

サポートされていない


replace

サポートされていない


rightPad

サポートされていない


rightTrim

サポートされていない


subQuery

サポートされていない


substring

サポートされている


toCharacter

サポートされていない


toDate

サポートされていない


toLowerCase

サポートされている


toNumber

サポートされている


toUpperCase

サポートされている


toUpperCasedWords

サポートされていない


translate

サポートされていない


trim

サポートされている


truncateDate

サポートされていない



脚注1 詳細は、108.7.1.5項「結合読取りとオブジェクト・レベルの読取り問合せ」を参照してください。

表108-9 ExpressionMath演算子でのインメモリー問合せのサポート

ExpressionMath演算子 インメモリー問合せのサポート

abs

サポートされている


acos

サポートされている


add

サポートされている


asin

サポートされている


atan

サポートされている


atan2

サポートされていない


ceil

サポートされている


chr

サポートされていない


cos

サポートされている


cosh

サポートされていない


exp

サポートされている


floor

サポートされている


ln

サポートされていない


log

サポートされている


max

サポートされている


min

サポートされている


mod

サポートされていない


none

サポートされていない


power

サポートされている


round

サポートされている


sign

サポートされていない


sin

サポートされている


sinh

サポートされていない


sqrt

サポートされている


subtract

サポートされている


tan

サポートされている


tanh

サポートされていない


trunc

サポートされていない



108.16.2.3 インメモリー問合せで発生した例外の処理

インメモリー問合せはいくつかの原因で失敗します。最も一般的な原因として次のことがあげられます。

  • 問合せ式が複雑すぎてメモリー内で実行できない場合。

  • インダイレクション(遅延ロード)が使用されている未トリガーのValueHolderがある場合。インダイレクションを使用するオブジェクト・モデルはすべて、関連オブジェクトに一致する前に、ValueHolderをトリガーする必要があります。

TopLinkは、インダイレクション例外を処理するためのメカニズムを提供します。アプリケーションでのインダイレクション例外の処理方法を指定するには、次のInMemoryQueryIndirectionPolicyメソッドを使用します。

  • throwIndirectionException: デフォルト設定です。インダイレクション例外をスローする唯一の設定です。

  • triggerIndirection: ValueHolderをすべてトリガーして問題を解消します。

  • ignoreIndirectionExceptionReturnConformed: 未トリガーのValueHolderが検出された場合に、一致された結果を返します。つまり、データベースから一致する結果が返される必要があり、対象となる属性が変更されていないことを示す未トリガーのValueHolderが取得されるようにする必要がある場合に、このオプションを選択します。

  • ignoreIndirectionExceptionReturnNotConformed: 未トリガーのValueHolderが検出された場合に、非一致な結果を返します。


    注意:

    新規アプリケーションを作成する際には、一致例外をすべてスローすることを検討してください。そうすることで、インメモリー問合せの失敗に関して、より詳しいフィードバックが得られます。詳細は、115.16.4.2項「一致するときの例外処理」を参照してください。

108.16.3 主キー問合せとキャッシュ

問合せでシングル・オブジェクトが主キーによって検索される場合、TopLinkでは、問合せから主キーを抽出し、データベースにアクセスせずにキャッシュからオブジェクトを返そうとします。オブジェクトがキャッシュ内に存在しない場合は、問合せはデータベースに対して実行され、結果のオブジェクトが作成されて、アイデンティティ・マップに配置されます。

問合せが主キー以外の選択基準に基づいている場合やすべて読取り問合せの場合、その問合せはデータベースに対して実行されます(ReadObjectQueryまたはReadAllQueryのメソッドcheckCacheOnlyを使用していない場合)。問合せでは、結果セットの主キーがキャッシュ内のオブジェクトと照合され、キャッシュされたオブジェクトがあれば、結果セットに入れて返されます。

オブジェクトがキャッシュ内に存在しない場合、オブジェクトが作成されます。問合せがリフレッシュ問合せの場合は、すべてのオブジェクトの内容が問合せの結果セットで更新されます。アイデンティティ・マップを正しく構成して使用する場合は、オブジェクト・アイデンティティに対してequalsを使用します。

クライアントは、ある時点でデータが最新の状態になるように、オブジェクトをいつでもリフレッシュできます。

複合主キーを使用したリレーションシップの走査

複合主キーを使用してリレーションシップを走査し、オブジェクトを取得する場合、問合せキーを作成して使用する必要があります(110.4項「問合せキーと問合せ式」を参照)。複合主キーを含むクラスのマップされた属性ごとに問合せキーを追加することにより、TopLinkでキャッシュの主キーを使用できます。

2つの属性(AおよびB)を含むMyClassというクラスについて検討してみます。ABは、両方とも1対1マッピングとしてデータベースにマップされており、主キーとして指定されています。

この場合、属性ごとに問合せキー(MyQueryKeyAおよびMyQueryKeyBなど)を作成し、他のクラスを経由せずにMyClassの主キーの属性をマップする必要があります。これで、この問合せキーを使用してキャッシュ内のオブジェクトを検索し、次のようにオブジェクトの主キーを問い合せることができます。

builder.get("MyQueryKeyA").equal(new Long("123456"));

108.16.4 読取り問合せ中のアイデンティティ・マップ・キャッシュの更新を無効にする方法

通常は読取り問合せによって実行されるアイデンティティ・マップ・キャッシュの更新を無効にするには、dontMaintainCacheメソッドをコールします。これによって、後でアプリケーションで必要とされないオブジェクトを読み取る際に、問合せのパフォーマンスが向上し、部分オブジェクト問合せ中に例外を回避できます(109.2.1.2項「部分オブジェクト問合せを使用したオブジェクトの読取り」を参照)。

例108-1は、コードがデータベースからEmployeeオブジェクトを読み取り、その情報をファイルに書き込む方法を示します。

例108-1 アイデンティティ・マップ・キャッシュの更新の無効化

// Reads objects from the employee table and writes them to an employee file
void writeEmployeeTableToFile(String filename, Session session) {
    Vector employeeObjects;
    // Create ReadAllQuery and set Employee as its reference class
    ReadAllQuery query = new ReadAllQuery(Employee.class);
    ExpressionBuilder builder = query.getExpressionBuilder();
    query.setSelectionCriteria(builder.get("id").greaterThan(100));
    query.dontMaintainCache();
    Vector employees = (Vector) session.executeQuery(query);
    // Write all the employee data to a file
    Employee.writeToFile(filename, employees);
}

108.16.5 キャッシュのリフレッシュ方法

キャッシュ内のオブジェクトをリフレッシュすることで、オブジェクトをデータベースに対して最新の状態に保つとともに、オブジェクト・アイデンティティを維持することができます。この項では、問合せAPIを使用して次のことを実行する方法について説明します。

108.16.5.1 オブジェクトのリフレッシュ

データベースのデータを使用してキャッシュ内のオブジェクトをリフレッシュするには、SessionのメソッドrefreshObjectまたはReadObjectQueryのメソッドsetShouldRefreshIdentityMapResult(true)をコールします。

108.16.5.2 オブジェクトのカスケード・リフレッシュ

オブジェクトとその関連オブジェクトがリフレッシュによって更新される深さを制御できます。次の3つのオプションがあります。

  1. CascadePrivateParts: デフォルトのリフレッシュ動作。ローカル・レベルのオブジェクトと、プライベートに所有されたリレーションシップで参照されるオブジェクトをリフレッシュします。

  2. CascadeNone: オブジェクトの最初のレベルのみをリフレッシュします。関連オブジェクトはリフレッシュしません。

  3. CascadeAll: オブジェクト・ツリー全体をリフレッシュし、リーフ・オブジェクトに達したときに停止します。

  4. CascadeMapping: カスケード・リフレッシュするように構成されている各マッピングをリフレッシュします。

108.16.5.3読取り問合せ中のアイデンティティ・マップ・キャッシュのリフレッシュ

アイデンティティ・マップを問合せの結果で強制的にリフレッシュするには、次の例に示すように、refreshIdentityMapResultメソッドを問合せに含めます。

例108-2 読取り問合せ中にアイデンティティ・マップ・キャッシュ内の問合せ結果をリフレッシュ

// Create ReadObjectQuery and set Employee as its reference class
ReadObjectQuery query = new ReadObjectQuery(Employee.class);
ExpressionBuilder builder = query.getExpressionBuilder();
query.setSelectionCriteria(builder.get("lastName").equal("Smith"));
query.refreshIdentityMapResult();
Employee employee = (Employee) session.executeQuery(query);

refreshIdentityMapResultメソッドは、オブジェクトの属性をリフレッシュしますが、私有部分の属性はリフレッシュしません。ただし、ほとんどの状況では、オブジェクトの私有部分とその他の関連オブジェクトをリフレッシュして、データベースとの整合性を維持してください。

プライベートに所有された部分や関連部分をリフレッシュするには、次のメソッドを使用します。

  • cascadePrivateParts: 私有オブジェクトをすべてリフレッシュします。

  • cascadeAllParts: 関連オブジェクトをすべてリフレッシュします。

例108-3 cascadePrivatePartsメソッドの使用

ReadAllQuery query = new ReadAllQuery(Employee.class);
query.refreshIdentityMapResult();
query.cascadePrivateParts();
Vector employees = (Vector) session.executeQuery(query);

注意:

オブジェクトがセッション・キャッシュ内に存在する場合、refreshObjectメソッドを使用して、オブジェクトとその私有部分をリフレッシュすることもできます。

108.16.6 セッション・キャッシュへの問合せ結果のキャッシュ方法

デフォルトでは、問合せ結果はセッション・キャッシュに格納されるため、データベースにアクセスせずに問合せを繰り返し実行することが可能になります。これは、静的データに対して問合せを実行する際に便利です。

探しているオブジェクトの数は認識されていないため、デフォルトでは、すべて読取り問合せは常にデータベースに送信されます。ただし、オブジェクトがすでにキャッシュ内に存在する場合は、行から新規オブジェクトを作成する必要がないため、時間の節約になります。

詳細は、第102章「キャッシュの概要」を参照してください。

108.16.7問合せキャッシュへの問合せ結果のキャッシュ方法

TopLinkでは、オブジェクト・キャッシュの他に、問合せキャッシュもサポートしています。この2つの間には次の違いがあります。

  • オブジェクト・キャッシュでは、主キーによってオブジェクトに索引付けし、主キー問合せでキャッシュ・ヒットを取得できるようにします。オブジェクトがすでに存在する場合、オブジェクト・キャッシュの使用により、データ・ソースにアクセスする問合せでは、オブジェクトおよびそれらのリレーションシップを作成する負荷を回避できます。

  • 問合せキャッシュは、オブジェクト・キャッシュとは異なります。問合せキャッシュは、オブジェクトの主キーではなく問合せおよび問合せパラメータによって索引付けされます。これにより、同じパラメータを使用して実行されたすべての問合せが、問合せキャッシュ・ヒットを取得し、同じ結果セットを返すことができます。

デフォルトでは、ReadQueryは、その問合せ結果セットをキャッシュしません。ただし、結果セットをキャッシュするように問合せを構成することはできます。これは、結果セットが変わることがまれにしかない問合せを頻繁に実行する際に便利です。問合せキャッシュでは、結果セットに対するハード参照は常に維持されます。異なるパラメータに対する、問合せキャッシュに保存される結果セットの数を構成することは、可能です。問合せキャッシュは、異なるパラメータを使用して最近実行した各問合せのサイズ値を維持します。

詳細は、111.13.1項「ReadQueryでの結果のキャッシュ方法」を参照してください。

キャッシュの無効化ポリシーを問合せの内部キャッシュに適用できます(111.13.2項「問合せレベルにおけるキャッシュの有効期限の構成方法」を参照)。詳細は、102.2.5項「キャッシュの無効化」を参照してください。

108.16.7.1 内部問合せキャッシュの制限

TopLinkでは、カーソルでの問合せキャッシュの使用をサポートしません。カーソルで問合せキャッシュを使用すると、例外がスローされます。カーソルの問合せの結果の詳細は、108.5.3項「ストリームとカーソルの問合せの結果」および111.11項「カーソルとストリームの問合せ結果の処理」を参照してください。

108.16.8 キャッシュとEJB 2.n CMPファインダの使用方法

TopLinkでは、EJBファインダが取得するEnterprise Beanをキャッシュします。アプリケーションに対し、EJBファインダの結果のキャッシュを様々な方法で構成できます。また、キャッシュのリフレッシュを強制したり、キャッシュを無効化することができます。

この項の内容は次のとおりです。

108.16.8.1 キャッシュ・オプション

基礎となる問合せに各種構成を適用して、アプリケーションにとって正しいキャッシュ動作を実現することができます。問合せのキャッシュ・オプションを制御するには、いくつかの方法があります。ほとんどの問合せでは、Oracle JDeveloperまたはTopLink Workbenchを使用してキャッシュ・オプションを設定できます。

キャッシュ・オプションはファインダ単位で設定できます。表108-10は、有効な値を示します。

表108-10 ファインダのキャッシュ・オプション

設定 ファインダの動作 検索に使用されるファインダの動作

ConformResultsInUnitOfWork脚注1

セッション・キャッシュまたはデータベースに対して問合せを行う前に、作業ユニットのキャッシュをチェックします。ファインダの結果は必ず、未コミットの新規オブジェクト、削除されたオブジェクト、および変更されたオブジェクトに一致します。

単一のBeanまたはコレクションを返します。

DoNotCheckCache

TopLinkの内部キャッシュをバイパスして、データベースに対して問合せを行います。

単一のBeanまたはコレクションを返します。

CheckCacheByExactPrimaryKey

オブジェクトのセッション・キャッシュをチェックします。

主キーのみを含み、単一のBeanを返します。

CheckCacheByPrimaryKey

オブジェクトのセッション・キャッシュをチェックします。

主キーを含み(その他の検索パラメータを含む場合もあります)、単一のBeanを返します。

CheckCacheThenDatabase

データベースにアクセスする前に、セッション・キャッシュで検索を行います。

単一のBeanを返します。

CheckCacheOnly

親セッション・キャッシュのみを検索し(作業ユニットのキャッシュは検索しない)、データベースは検索しません。

単一のBeanまたはコレクションを返します。


脚注1 デフォルトです。

TopLink問合せとTopLinkの作業ユニット、およびJTSへの作業ユニットの統合方法の詳細は、第113章「TopLinkトランザクションの概要」を参照してください。


注意:

手動で作成した問合せ(findOneByQueryfindManyByQuery)によってファインダにキャッシュ・オプションを適用するには、TopLink APIを使用します。

108.16.8.2 返されたファインダ結果のキャッシュの無効化

デフォルトでは、返されたオブジェクトはすべてセッション・キャッシュに追加されます。ただし、返されるオブジェクトが非常に大きいとわかっている場合に、そのオブジェクトを格納する負荷を回避するには、この動作を無効にします。デフォルト構成をオーバーライドするには、dontMaintainCacheメソッドを問合せに実装するか、Oracle JDeveloperまたはTopLink Workbenchで、返されたオブジェクトのキャッシュを問合せに対して無効にします。

108.16.8.3 ファインダ結果のリフレッシュ

ファインダは、主キーがすでにキャッシュ内にあるオブジェクトの情報を、データベースから返すことができます。Oracle JDeveloperおよびTopLink Workbenchでキャッシュ・リフレッシュ・オプションをTRUEに設定すると、問合せにより、オブジェクトの主キー以外の属性が、返された情報でリフレッシュされます。この処理は、findByPrimaryKeyファインダだけではなく、Beanのすべての式ファインダおよびSQLファインダでも行われます。

問合せをJavaコードで作成する場合、refreshIdentityMapResultメソッドを含めることで、このオプションを設定できます。このメソッドは、変更をBeanのプライベートに所有された部分に自動的にカスケードします。異なる動作が必要な場合は、動的ファインダを使用して問合せを構成します。


注意:

このオプションをトランザクション内から起動すると、リフレッシュ処理により、オブジェクトの属性(まだデータベースに書き込まれていないものも含む)が上書きされます。

アプリケーションにOptimisticLockフィールドが含まれている場合、キャッシュ・リフレッシュ・オプションをonlyRefreshCacheIfNewerVersionオプションと併用します。そうすることで、データベース内のオブジェクトのバージョンがキャッシュ内のバージョンよりも新しい場合にのみ、キャッシュ内のオブジェクトがリフレッシュされます。

キャッシュ・リフレッシュ設定を持たないファインダの場合、onlyRefreshCacheIfNewerVersionメソッドは効果がありません。

108.17 問合せAPI

表108-11では、セッション・タイプごとにどの問合せをサポートしているかを示します。セッション・タイプごとに、実行できる問合せ操作(作成、読取り、更新、削除)のタイプとDatabaseQueryまたはCallを実行できるかどうかを示します。たとえば、作業ユニットを使用する場合は、セッション問合せを使用して読取りおよび削除ができます。サーバー・セッションを使用する場合は、セッション問合せを使用して作成、読取り、更新および削除ができます。

表108-11 セッション問合せAPIのサマリー

セッション 作成 読取り 更新 削除 データベース問合せの実行 コールの実行

作業ユニット

サポートされていない
サポートされている
サポートされていない
サポートされている
サポートされている
サポートされている

データベース

サポートされている
サポートされている
サポートされている
サポートされている
サポートされている
サポートされている

サーバー

サポートされていない
サポートされていない
サポートされていない
サポートされていない
サポートされていない
サポートされていない

クライアント

サポートされていない
サポートされている
サポートされていない
サポートされていない
サポートされている
サポートされている

例108-4では、問合せと式をサポートする基本的なTopLinkパッケージを示します。

例108-4 問合せと式のパッケージ

oracle.toplink.queryframework
oracle.toplink.expressions
oracle.toplink.querykeys
oracle.toplink.descriptors.DescriptorQueryManager