リレーショナル・マッピングは、オブジェクトのデータ・メンバー・タイプを、サポートされているリレーショナル・データベースの対応するリレーショナル・データベース(SQL)のデータ・ソース表現に変換します。リレーショナル・マッピングを使用すると、オブジェクト・モデルをリレーショナル・データ・モデルにマップすることができます。
リレーショナル・マッピングは、オブジェクト・データ・メンバーをリレーショナル・データベース・フィールドに変換します。これらを使用して、プリミティブを含む単純なデータ・タイプ(int
など)、JDKクラス(String
など)およびラージ・オブジェクト(LOB)の値をマップします。また、これらを使用して、データ・ソース表現にオブジェクト・アイデンティティの維持(順序付けおよび後方参照など)が必要な関連付けによって、他のドメイン・オブジェクトを参照するオブジェクト・データ・メンバーを変換し、多重度および誘導可能性の様々なタイプを持たせることもできます。適切なマッピング・クラスは、主にリレーションシップのカーディナリティによって選択されます。
リレーショナル・マッピングとオブジェクト・リレーショナル・データ・タイプ・マッピングは混同しないでください(第40章「オブジェクト・リレーショナル・データ・タイプ・マッピングの概要」を参照)。オブジェクト・リレーショナル・データ・タイプ・マッピングは、特定オブジェクトのデータ・メンバー・タイプを、Oracle Databaseのような特別なオブジェクト・リレーショナル・データ・タイプ・データベースでの格納に最適化された構造化データ・ソース表現に変換します。オブジェクト・リレーショナル・データ・タイプ・マッピングを使用すると、オブジェクト・モデルをオブジェクト・リレーショナル・データ・タイプ・データ・モデルにマップできます。通常、リレーショナル・マッピングは、サポートされているすべてのリレーショナル・データベースで使用できます。オブジェクト・リレーショナル・データ・タイプ・マッピングは、オブジェクト・リレーショナル・データ・タイプ・データ・ソース表現をサポートするために最適化された特別のオブジェクト・リレーショナル・データ・タイプ・データベースにのみ使用できます。
この章の内容は次のとおりです。
複数のタイプのTopLinkマッピングに共通のマッピングの概念と機能の詳細は、第17章「マッピングの概要」を参照してください。
TopLinkでは、表27-1に示すリレーショナル・マッピングをサポートしています。
表27-1 TopLinkリレーショナル・マッピングのタイプ
マッピングのタイプ | 説明 | Oracle JDeveloper |
TopLink Workbench | Java |
---|---|---|---|---|
フィールドへ直接(27.3項「フィールドへ直接マッピング」を参照) |
Java属性をデータベース・フィールドに直接マップします。 |
![]() |
![]() |
![]() |
XMLタイプへ直接(27.4項「XMLタイプへ直接マッピング」を参照) |
Java属性をOracleデータベースの |
![]() |
![]() |
![]() |
1対1(27.5項「1対1マッピング」を参照) |
他の永続Javaオブジェクトへの参照をデータベースにマップします。 |
![]() |
![]() |
![]() |
可変1対1(27.6項「可変1対1マッピング」を参照) |
インタフェースへの参照をデータベースにマップします。 |
![]() |
![]() |
![]() |
1対多(27.7項「1対多マッピング」を参照) |
永続オブジェクトのJavaコレクションをデータベースにマップします。 |
![]() |
![]() |
![]() |
多対多(27.8項「多対多マッピング」を参照) |
関連表を使用して、永続オブジェクトのJavaコレクションをデータベースにマップします。 |
![]() |
![]() |
![]() |
集約コレクション(27.9項「集約コレクション・マッピング」を参照) |
永続オブジェクトのJavaコレクションをデータベースにマップします。 |
|
|
![]() |
ダイレクト・コレクション(27.10項「ダイレクト・コレクション・マッピング」を参照) |
ディスクリプタを持たないオブジェクトのJavaコレクションをマップします。 |
![]() |
![]() |
![]() |
ダイレクト・マップ(27.11項「ダイレクト・マップ・マッピング」を参照) |
ダイレクト・マップ・マッピングでは、 |
![]() |
![]() |
![]() |
集約オブジェクト(27.12項「集約オブジェクト・マッピング」を参照) |
オブジェクトが両方とも同じデータベース行に存在する必要がある、厳密な1対1マッピングを作成します。 |
![]() |
![]() |
|
トランスフォーメーション(27.13項「トランスフォーメーション・マッピング」を参照) |
カスタム・マッピングを作成し、1つ以上のフィールドを使用して属性に格納するオブジェクトを作成できるようにします。 |
![]() |
![]() |
![]() |
この項では、次のようなTopLinkに固有のダイレクト・マッピングの概念について説明します。
リレーションシップの方向性は、単方向または双方向のいずれかです。単方向リレーションシップでは、一方のエンティティBeanのみが、他方のBeanを参照するリレーションシップ・フィールドを持ちます。すべてのTopLinkリレーショナル・マッピングは、記述されるクラス(ソース・クラス)から関連付けられるクラス(ターゲット・クラス)への単方向です。単方向リレーションシップでは、ターゲット・クラスはソース・クラスへの参照を持ちません。
双方向リレーションシップでは、各エンティティBeanが、他のBeanを参照するリレーションシップ・フィールドを持ちます。リレーションシップ・フィールドの使用により、エンティティBeanのコードは関連するオブジェクトにアクセスできます。双方向リレーションシップ(相互に参照するクラス)を実装するには、ソースおよびターゲットを逆にしたものと合せ、2つの単方向マッピングを使用します。
注意: 双方向リレーションシップを維持するには、いくつかの技術上の課題があります。詳細は、次を参照してください。 |
次の方法でオブジェクト属性をデータベース表に直接格納できます。
ダイレクト・マッピング(27.2.2.1項「ダイレクト・マッピングの使用」を参照)
コンバータ・マッピング(27.2.2.2項「コンバータ・マッピングの使用」を参照)
トランスフォーメーション・マッピング(27.2.2.3項「トランスフォーメーション・マッピングの使用」を参照)
属性タイプがデータベース・タイプに相当する場合、フィールドへ直接マッピングを使用するのみで、情報を直接格納できます(27.3項「フィールドへ直接マッピング」を参照)。
属性タイプがデータベース・タイプに相当しますが、変換が必要な場合、フィールドへ直接マッピング(27.3項「フィールドへ直接マッピング」を参照)と適切なConverter
インスタンスを使用して、情報を直接格納できます。
以前のリリースでは、TopLinkはオブジェクト・タイプ・ダイレクト・マッピング、シリアライズ・オブジェクト・ダイレクト・マッピングおよびタイプ変換ダイレクト・マッピングに対してサブクラスのDirectToFieldMapping
を提供していました。今回のリリースでは、これらのサブクラスは非推奨です。そのかわりに、DirectToFieldMapping
メソッドsetConverter
およびそれに対応するConverter
インスタンスの使用をお薦めします。表27-2では、これらの変更を示します。
表27-2 フィールドへ直接マッピングのコンバータの使用
非推奨のDirectToFieldMappingサブクラス | Converterインスタンスによる置換 |
---|---|
|
|
|
|
|
|
アプリケーションのオブジェクトに、既存のコンバータを使用してフィールドへ直接として表現できない属性が含まれる場合、カスタム・コンバータでフィールドへ直接マッピングを使用します。
論理的に属性のタイプに相当するデータベース・プリミティブ・タイプがない場合、または属性が複数フィールドからのデータを必要とする場合、データベースへの方向およびデータベースからの方向で変換する必要があります。
この場合、トランスフォーメーション・マッピングを使用します(27.13項「トランスフォーメーション・マッピング」を参照)。
ダイレクト・マッピングを使用して、Beanの(非CMR)CMF属性をマップします。
EJB CMPプロジェクトでは、Beanクラスはクラス内で実際の変数を定義しません(抽象getterメソッドおよびsetterメソッドのみ)。Beanの属性をマップするには、ejb-jar.xml
ファイルをTopLink Workbenchにインポートする必要があります(117.5項「永続性タイプの構成」を参照)。
エンティティBean属性は、ダイレクト・マッピングを使用すれば特別な考慮を必要とせずにマップできます。
1対1マッピング(27.5.1項「1対1マッピングとEJB 2.n CMP」を参照)、1対多マッピング(27.7.1項「1対多マッピングとEJB 2.n CMP」を参照)および多対多マッピング(27.8.1項「多対多マッピングとEJB 2.n CMP」を参照)を使用する際、いくつかの特別な考慮事項があります。
フィールドへ直接マッピングは、プリミティブ・オブジェクト属性またはJDKクラスなどの非永続標準オブジェクトをマップするために使用します。たとえば、フィールドへ直接マッピングは、String
属性をVARCHAR
フィールドに格納する際に使用します。
図27-1は、Java属性city
の、リレーショナル・データベース列CITY
フィールドへの直接マッピングを示します。同様に、country
からCOUNTRY
、id
からEMP_ID
、established
からEST_DATE
およびprovince
からPROVINCE
に、フィールドへ直接マッピングを定義することができます。
次のいずれかのConverter
インスタンスを使用して、フィールドへ直接マッピングを使用できます。
オブジェクト・タイプ・コンバータ(17.2.6.3項「オブジェクト・タイプ・コンバータ」を参照)
シリアライズ・オブジェクト・コンバータ(17.2.6.1項「シリアライズ・オブジェクト・コンバータ」を参照)
タイプ変換コンバータ(17.2.6.2項「タイプ変換コンバータ」を参照)
フィールドへ直接マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第29章「リレーショナル・フィールドへ直接マッピングの構成」を参照してください。
XMLタイプへ直接マッピングを使用して、String
の形式またはorg.w3c.dom.Document
オブジェクトの形式でXMLデータをOracleデータベース(バージョン9.2.0.1で採用)のXMLType列にマップできます。
TopLink WorkbenchおよびTopLinkランタイムでXMLType
へ直接マッピングを使用する場合は、TopLink WorkbenchクラスパスにOracleデータベースxdb.jar
ファイルを追加する必要があります(5.2項「TopLink Workbench環境の構成」を参照)。
TopLinkの問合せフレームワークでは、XMLデータの内容に基づく問合せの作成に必要ないくつかの式演算子が提供されます(110.2.4項「XMLType関数」を参照)。
詳細は、第30章「リレーショナルXMLタイプへ直接マッピングの構成」を参照してください。
1対1マッピングは、2つのJavaオブジェクト間の単純なポインタ参照を表します。Javaでは、属性に格納される単一のポインタが、ソース・オブジェクトとターゲット・オブジェクト間のマッピングを表します。リレーショナル・データベース表は、外部キーを使用してこれらのマッピングを実装します。
図27-2は、Employee
オブジェクトのaddress
属性からAddress
オブジェクトへの1対1リレーションシップを示します。このリレーションシップをデータベースに格納するには、address
属性とAddress
クラス間の1対1マッピングを作成します。このマッピングは、Employee
インスタンスが書き込まれる際にEMPLOYEE
表のAddress
インスタンスのid
を格納します。また、Employee
がデータベースから読み取られる際に、Employee
インスタンスをAddress
インスタンスにリンクします。Address
にはEmployee
への参照がないため、Employee
へのマッピングを提供する必要がありません。
通常、1対1マッピングの場合、ソース表にはターゲット表のレコードへの外部キー参照が含まれます。図27-2では、EMPLOYEE
表のADDR_ID
フィールドが外部キーです。
ターゲット表にソース表への外部キー参照が含まれる、1対1マッピングを実装することもできます。図27-2では、ADDRESS
行が属しているEmployee
を識別するためにEMP_ID
を含むように、データベース設計が変更されます。この場合、ターゲットにもソースへのリレーションシップ・マッピングを持たせる必要があります。
更新、挿入および削除の操作は、通常、私有された1対1リレーションシップの場合はソースの前にターゲットに行われ、ターゲットが外部キーを所有する際には逆の順序で実行されます。ターゲット外部キーは通常、双方向の1対1マッピング(27.2.1項「方向性」を参照)で使用されます。これは、一方が外部キーを持ち、他方が自分の表で同じ外部キーを共有するためです。
ターゲット外部キーは、大規模カスケードのコンポジット主キーが存在する(つまり、1つのオブジェクトの主キーが多数の他のオブジェクトの主キーからなる)場合にも使用されます。この場合は、外部キーとターゲット外部キーの両方を含む1対1マッピングを持たせることができます。
外部キーでは、TopLinkによりオブジェクトの行の外部キーの値が自動的に更新されます。ターゲット外部キーでは、値は更新されません。TopLinkでは、ターゲット外部キー・リレーションシップが定義される際に「ターゲット外部キー」オプションを使用します。
リレーションシップをマッピングする際、リレーションシップが正しく定義されるようにするために、これらの外部キーとターゲット外部キーの相違点を理解する必要があります。
2つのクラスが相互参照する双方向リレーションシップでは、マッピングの1つのみに外部キーを持たせる必要があります。他のマッピングにはターゲット外部キーを持たせる必要があります。双方向リレーションシップのマッピングの1つが1対1マッピングである場合、詳細は第32章「リレーショナル可変1対1マッピングの構成」を参照してください。
1対1マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第31章「リレーショナル1対1マッピングの構成」を参照してください。
EJB準拠を維持するには、リレーションシップのターゲットを指すオブジェクト属性が、Beanクラスではなく、ローカル・インタフェース・タイプである必要があります。
TopLinkには、リレーションシップのターゲットが依存Javaオブジェクトである場合に、複合リレーションシップを定義できる1対1マッピングのバリエーションが用意されています。たとえば、可変1対1マッピングを使用すると、変数ターゲット・オブジェクトをリレーションシップに指定できます。これらのバリエーションは、エンティティBeanでは使用できませんが、依存Javaオブジェクトには有効です。
詳細は、第32章「リレーショナル可変1対1マッピングの構成」を参照してください。
可変クラス・リレーションシップは、ポリモーフィック・リレーションシップと似ていますが、この場合はターゲット・クラスが継承を介して関連付けられるのではなく(このため抽象表は不要)、インタフェースを介して関連付けられます。
TopLink Workbenchで可変クラス・リレーションシップを定義するには、可変1対1マッピング選択を使用しますが、参照クラスとしてインタフェースを選択します。これにより、マッピングが可変1対1となります。Javaコードでマッピングを定義する場合は、VariableOneToOneMapping
クラスを使用します。
TopLinkは、1対1マッピングでのみ可変リレーションシップをサポートします。このリレーションシップは、次の2つの方法で処理されます。
クラス・インジケータ・フィールドを使用(32.2項「クラス・インジケータの構成」を参照)
インタフェースを実装しているターゲット・クラスで一意の主キー値を使用(32.3項「一意の主キーの構成」を参照)
詳細は、第32章「リレーショナル可変1対1マッピングの構成」を参照してください。
1対多マッピングは、1つのソース・オブジェクトとターゲット・オブジェクトのコレクションの間のリレーションシップを表すために使用されます。1対多マッピングは、ターゲット・オブジェクトのCollection
(または他のコレクション・タイプ)によるJavaでの実装が簡単なものを示す一例です。
Java Collection
では、所有者がその一部を参照します。リレーショナル・データベースでは、その一部がその所有者を参照します。リレーショナル・データベースでは、この実装を使用して問合せをより効率的にします。
この1対1マッピングのターゲット内での作成は、ターゲット・オブジェクトを保存する際に外部キー情報を書込み可能にすることを目的としています。1対1マッピングの後方参照の代替方法には、次のものがあります。
フィールドへ直接マッピングを使用して、外部キーをマップし、その値をアプリケーション内で維持します。ここでは、オブジェクト・モデルでは後方参照を必要としませんが、データ・モデルではターゲット表の外部キーを必要とします。
多対多マッピングを使用して、論理的1対多を実装します。これは、オブジェクト・モデルで後方参照を必要としない、またデータ・モデルで外部キーを必要としないという利点があります。このモデルでは、多対多リレーション表にコレクションが格納されます。結合表に制限を加えて、リレーションが論理的1対多リレーションシップであることを実現します。
注意: 図27-4のphone 属性はタイプVector です。コレクション属性の宣言にはCollection インタフェース(またはCollection インタフェースを実装する任意のクラス)を使用できます。詳細は、121.14項「コンテナ・ポリシーの構成」を参照してください。 |
多対多マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第33章「リレーショナル1対多マッピングの構成」を参照してください。
1対多マッピングは、エンティティBean間のリレーションシップ、または1つのエンティティBeanと私有される標準Javaオブジェクトのコレクションの間のリレーションシップに対して使用します。1対多マッピングを作成する際に、ターゲット・オブジェクトからソースへの逆方向の1対1マッピングも作成します。Beanへのポインタが含まれるオブジェクト属性は、Beanクラスではなく、ローカル・インタフェース・タイプである必要があります。
TopLinkでは、Bean間の双方向リレーションシップを作成または更新すると、バックポインタを自動的に維持します。
詳細は、121.18項「双方向リレーションシップの構成」を参照してください。
多対多マッピングは、ソース・オブジェクトのコレクションとターゲット・オブジェクトのコレクションの間のリレーションシップを表します。この場合、ソースとターゲットのレコード間の関連を管理するための中間表の作成が必要です。
図27-5は、Javaの多対多マッピングおよびリレーショナル・データベース表の多対多マッピングを示します。
注意: 図27-5のprojects 属性はタイプVector です。コレクション属性の宣言にはCollection インタフェース(またはCollection インタフェースを実装する任意のクラス)を使用できます。詳細は、121.14項「コンテナ・ポリシーの構成」を参照してください。 |
多対多マッピングは、リレーション表を使用して実装されます。この表には、ソース表およびターゲット表の主キーの列が含まれます。コンポジット主キーは、コンポジット・キーの各フィールドの列を必要とします。多対多マッピングを使用する前に、中間表をデータベース内に作成する必要があります。
ターゲット・クラスでは、多対多マッピングに対する任意の動作を実装する必要はありません。ターゲット・クラスがそのソース・クラスへの逆方向の多対多マッピングも作成する場合、同じリレーション表を使用できますが、マッピングの一方を読取り専用に設定する必要があります。マッピングの表への書込みが両方とも可能な場合、衝突の原因になることがあります。
インダイレクション(遅延ロード)は多対多マッピングでデフォルトで有効であり、属性がValueHolderInterface
タイプであるか、透過コレクションを持つことを必要とします。インダイレクションの詳細は、17.2.4項「インダイレクション(遅延ロード)」を参照してください。
多対多マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第34章「リレーショナル多対多マッピングの構成」を参照してください。
CMPを使用する場合、多対多マッピングはエンティティBean間でのみ有効で、私有できません。唯一の例外は、多対多マッピングを使用して、リレーション表による論理的1対多マッピングを実装する場合です。
TopLinkでは、双方向リレーションシップを作成または更新すると、バックポインタを自動的に維持します。
詳細は、121.18項「双方向リレーションシップの構成」を参照してください。
集約コレクション・マッピングは、1つのソース・オブジェクトとターゲット・オブジェクトのコレクションの間の集約リレーションシップを表す場合に使用されます。TopLinkの1対多マッピングでは、ターゲット・オブジェクトからソース・オブジェクトへの逆方向の1対1参照マッピングが必要ですが、集約コレクション・マッピングはこれとは異なり、外部キー・リレーションシップが集約によって解決されるため、逆方向の参照は必要ありません。
注意: TopLink Workbenchによる集約コレクションを使用するには、修正メソッドを使用するか(119.35項「修正メソッドの構成」を参照)、手動でプロジェクト・ソースを編集してマッピングを追加する必要があります。 |
集約コレクション・マッピングは1対多マッピングに似ていますが、1対多マッピングのかわりではありません。ターゲット・コレクションが適当なサイズであり、逆方向の1対1マッピングが困難である場合にのみ、集約コレクションを使用します。
1対多リレーションシップの方がより高いパフォーマンスを発揮し、より堅牢でスケーラビリティに優れているため、集約コレクションではなく、1対多リレーションシップを使用することを検討してください。また、集約コレクションはリレーションシップのソースによってプライベートに所有され、他のオブジェクトによる共有および参照はできません。
この項の内容は次のとおりです。
詳細は、第35章「リレーショナル集約コレクション・マッピングの構成」を参照してください。
集約コレクション・ディスクリプタは継承を使用できます。また、集約コレクションとしてサブクラスを宣言する必要もあります。サブクラスは、独自のマップされた表を持つか、または親クラスと表を共有できます。継承の詳細は、16.2.2項「ディスクリプタと継承」を参照してください。
Java Collection
では、所有者がその一部を参照します。リレーショナル・データベースでは、その一部がその所有者を参照します。リレーショナル・データベースでは、この実装を使用して問合せをより効率的にします。
集約コレクション・マッピングには、ターゲット・オブジェクト用のターゲット表が必要です。
集約コレクション・マッピングを実装するには、次を実行する必要があります。
ターゲット・クラスのディスクリプタは、それ自体を集約コレクション・オブジェクトとして宣言する必要があります。集約オブジェクト・マッピングでは、ターゲット・ディスクリプタに特定の表を関連付けませんが、ターゲット・オブジェクトにはターゲット表が必要です。
ソース・クラスのディスクリプタは、ターゲット・クラスを指定する集約コレクション・マッピングを追加する必要があります。
リレーションシップのソースがエンティティBeanまたはJavaオブジェクト、マッピング・ターゲットが標準Javaオブジェクトである場合、集約コレクション・マッピングはエンティティBeanとともに使用できます。エンティティBeanは、集約オブジェクト・マッピングのターゲットにできません。
集約コレクション・マッピングを実装するには、次を実行する必要があります。
ターゲット・クラスのディスクリプタは、それ自体を集約コレクション・オブジェクトとして宣言する必要があります。集約オブジェクト・マッピングでは、ターゲット・ディスクリプタに特定の表を関連付けませんが、ターゲット・オブジェクトにはターゲット表が必要です。
ソース・クラスのディスクリプタは、ターゲット・クラスを指定する集約コレクション・マッピングを追加する必要があります。
ダイレクト・コレクション・マッピングでは、TopLink対応ではないJavaオブジェクトのコレクションを格納します。通常、ダイレクト・コレクションに格納されるオブジェクト・タイプは、String
などのJavaタイプです。
ダイレクト・コレクション・マッピングを使用して、String
以外のオブジェクトのコレクションをマップすることもできます。たとえば、Integer
またはDate
インスタンスのコレクションを含む属性を持つことができます。そのコレクションに格納されたインスタンスは、データベースでサポートされているいずれかのタイプになり、Javaで対応するラッパーを持ちます。
JavaのCollection
はオブジェクトのみを保持するため、int
などのプリミティブ・データ・タイプはサポートされません。
図27-6は、2つのフィールドのある別の表にダイレクト・コレクションを格納する方法を示します。最初のフィールドは参照キー・フィールドであり、コレクションを所有するインスタンスの主キーへの参照を含みます。2番目のフィールドは、コレクションのオブジェクトを含み、ダイレクト・フィールドと呼ばれます。コレクションの各オブジェクトに対して表に1つのレコードがあります。
注意: 図27-6のresponsibilities 属性はタイプVector です。コレクション属性の宣言にはCollection インタフェース(またはCollection インタフェースを実装する任意のクラス)を使用できます。詳細は、121.14項「コンテナ・ポリシーの構成」を参照してください。 |
マップは、キー値がないためダイレクト・コレクションではサポートされません。
次のいずれかのConverter
インスタンスを使用して、ダイレクト・コレクション・マッピングを使用できます。
ダイレクト・コレクション・マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第36章「リレーショナル・ダイレクト・コレクション・マッピングの構成」を参照してください。
ダイレクト・マップ・マッピングでは、java.util.Map
を実装するインスタンスが格納されます。1対多または多対多マッピングとは異なり、この種のマッピングのマップのキーおよび値は、ディスクリプタを持たないJavaオブジェクトです。ダイレクト・マップのキーおよび値に格納されるオブジェクト・タイプは、String
オブジェクトなどのJavaプリミティブ・ラッパー・タイプです。
図27-7は、3つのフィールドのある別の表にダイレクト・マップを格納する方法を示します。最初のフィールド(EMPID
)は参照キー・フィールドで、コレクションを所有するインスタンスの主キーへの参照を含みます。2番目のフィールド(ADDRESS
)は、コレクションのオブジェクトを含み、ダイレクト値フィールドと呼ばれます。3番目のフィールド(TYPE
)は、ダイレクト・キー・フィールドを含みます。この例では、ダイレクト・マップがダイレクト・キー・フィールドのオブジェクト・タイプ・コンバータを使用し、データベースの単一の文字Wをオブジェクトの完全な文字列Workに(またHをHomeに)変換します。
次のいずれかのConverter
インスタンスを使用して、ダイレクト・コレクション・マッピングを使用できます。
ダイレクト・マップ・マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
詳細は、第38章「リレーショナル・ダイレクト・マップ・マッピングの構成」を参照してください。
2つのオブジェクト、つまり、ソース(親、すなわち所有)オブジェクトとターゲット(子、すなわち被所有)オブジェクトは、両者間に厳密な1対1の関係がある場合、集約によって関連付けられ、ターゲット・オブジェクトのすべての属性は、ソース・オブジェクトと同じ表から取得できます。つまり、ソース・オブジェクトが存在すればターゲット・オブジェクトも存在する必要があり、ソース・オブジェクトが破棄されればターゲット・オブジェクトも破棄されるということです。
集約マッピングにより、ターゲット・オブジェクト内のデータ・メンバーを、ソース・オブジェクトの基礎となるデータベース表のフィールドと関連付けることができます。
ソース・オブジェクトのディスクリプタの集約マッピングを構成します。ただし、構成する前に、ターゲット・オブジェクトのディスクリプタを集約として指定する必要があります(23.6項「クラスまたは集約タイプとしてのリレーショナル・ディスクリプタの構成」を参照)。
集約オブジェクトは私有され、他のオブジェクトによる共有または参照はできません。
集約ではないオブジェクトから集約ターゲット・オブジェクトへの1対1マッピング、1対多マッピングまたは多対多マッピングは構成できません。
集約ターゲット・オブジェクトから別の集約ではないオブジェクトへのマッピングは構成できます。集約ターゲット・オブジェクトから別の集約ではないオブジェクトへの1対多マッピングを構成する場合、別のオブジェクトから(集約ターゲット・オブジェクト自体ではなく)集約を所有するソース・オブジェクトに逆方向に1対1マッピングを構成する必要があります。これは、ソース・オブジェクトが集約ターゲットの表および主キー情報を含むためです。
集約として定義されたディスクリプタ(16.2.2項「ディスクリプタと継承」を参照)で継承を構成できますが、その場合は継承ツリー内のすべてのディスクリプタが集約である必要があります。集約ディスクリプタとクラス・ディスクリプタは、同じ継承ツリーに置くことはできません。
この項の内容は次のとおりです。
集約オブジェクト・マッピングは、変更ポリシーで使用できます(119.30項「変更ポリシーの構成」を参照)。
集約オブジェクト・リレーションシップ・マッピングの構成の詳細は、第37章「リレーショナル集約オブジェクト・マッピングの構成」を参照してください。
図27-8は、ソース・オブジェクトEmployee
とターゲット・オブジェクトPeriod
の間の集約オブジェクト・マッピングの例を示します。この例では、ターゲット・オブジェクトは他のソース・オブジェクトのタイプとは共有されません。
複数ソース・クラス間で共有されない集約ターゲット・クラスは、他の集約オブジェクト・マッピングを含む任意のタイプのマッピングを持つことができます。
図27-9は、異なるソース・オブジェクト(Employee
およびProject
)が同じターゲット・オブジェクトのタイプPeriod
のインスタンスをマップする、集約オブジェクト・マッピングの例を示します。
ソース・オブジェクトで集約オブジェクト・マッピングを構成する場合、その特定のマッピングに対するソース・オブジェクト表を選択します。これにより、異なるソース・タイプがそれぞれの表内に同じターゲット情報を格納できます。それぞれのソース・オブジェクトの表で、異なるフィールド名を使用できます。TopLinkでは、複数のソース・オブジェクト表が異なるフィールド名を使用するようなケースは自動的に管理されます。
たとえば、図27-9では、Employee
属性employPeriod
が集約オブジェクト・マッピングによりターゲット・オブジェクトPeriod
にマップされます。このマッピングは、Period
属性startDate
をEMPLOYEE
表のフィールドSTART_DATE
に関連付けます。Project
属性projectPeriod
も、集約オブジェクト・マッピングによりターゲット・オブジェクトPeriod
にマップされます。このマッピングは、Period
属性startDate
をPROJECT
表のフィールドS_DATE
に関連付けます。
複数のソース・クラスで共有される集約ターゲット・クラスは、1対多または多対多マッピングを持つことができません。
必ず次のように実行してください。
ターゲット・クラスのディスクリプタは、それ自体を集約コレクション・オブジェクトとして宣言する必要があります。すべての情報はその親の表から取得されるため、ターゲット・ディスクリプタにはその情報に関連付けられた特定の表がありません。しかし、ターゲットのマッピングに使用できる表のいずれかを1つ以上選択する必要があります。
前述の例では、EMPLOYEE
表を選択できるため、START_DATE
およびEND_DATE
フィールドがマッピング中に使用可能になります。
ソース・クラスのディスクリプタは、ターゲット・クラスを指定する集約オブジェクト・マッピングを追加します。
前述の例では、Employee
クラスには、employPeriod
と呼ばれる属性があり、これは参照クラスとしてPeriod
を使用して集約オブジェクト・マッピングとしてマップされます。
ソース・クラスでは、必ずその表にターゲット・クラスで登録されたフィールド名に一致するフィールドがある必要があります。
ソース・オブジェクトにnull
ターゲット参照がある場合、TopLinkではNULLを集約データベース・フィールドに書き込みます(37.3項「許容NULL値の構成」を参照)。ソースがデータベースから読み取られる際、次の2つの方法のいずれかでこのnull
ターゲットを処理できます。
null
と等しい属性すべてを持つオブジェクトのインスタンスを作成します。
ターゲットをインスタンス化せずに、ソース・オブジェクトにnull
参照を加えます。(これは、null
ターゲットを処理するデフォルトのメソッドです。)
値をJavaで表す方法とデータベースで表す方法の間の特殊な変換に、トランスフォーメーション・マッピングを使用します。
ヒント: トランスフォーメーション・マッピングは、複数のフィールドを1つの属性にマップする場合にのみ使用します。トランスフォーメーション・マッピングは複雑なため、多くの場合、コンバータまたはフィールドへ直接マッピングのgetterおよびsetterメソッドを使用する方が簡単に変換を実行できます。詳細は、第29章「リレーショナル・フィールドへ直接マッピングの構成」を参照してください。 |
図27-10は、トランスフォーメーション・マッピングを示します。B_DATE
およびB_TIME
フィールドからの値は、birthDate
属性に格納されるjava.util.Date
の作成に使用されます。
多くの場合、トランスフォーメーション・マッピングは、複数のフィールドの値を使用して1つのオブジェクトを作成する場合に適しています。このタイプのマッピングには、オブジェクトをデータベースから読み取る際に起動される属性トランスフォーメーションの設定が必要です。これには、Record
のインスタンスであるパラメータを少なくとも1つ持たせる必要があります。属性トランスフォーメーションでは、特定の列の値の取得にRecord
メソッドget
を使用できます。属性トランスフォーメーションは、Session
のインスタンスである場合、2番目のパラメータを指定できます。Session
は、トランスフォーメーションで必要な追加の値を取得するために、データベースで問合せを実行します。トランスフォーメーションは、属性に格納される値を返す必要があります。
トランスフォーメーション・マッピングでも、オブジェクトの保存時にデータベースに書き込まれる、各フィールドのフィールド・トランスフォーメーションを必要とします。トランスフォーメーションは、そのフィールドに格納される値を返します。
詳細は、第39章「リレーショナル・トランスフォーメーション・マッピングの構成」を参照してください。