9

アプリケーションを作成し、モデルに ORM を使用することを計画していましたが、エンティティ属性値テーブルを使用するデータベースの一部があります。

私は Doctrine ORM がかなり気に入りましたが、実際に接続されているテーブルが EAV スタイルである場合、通常の教義エンティティのように見えるクラスを作成できるかどうかはわかりません。

これに Doctrine を使用することは可能でしょうか。

4

2 に答える 2

5

確実に可能:

次のような関係を持ちます: オブジェクト (1 対多) -> AttributeValue -> 多対 1 -> AttributeType

于 2013-01-14T23:19:20.923 に答える
2

EAVの観点からすると、ドクトリンentityとドクトリンの使用との間の関係を構築する方法は明らかであるように思われますattribute。最も複雑なケースでは、多対多の関係を扱います。

それでは、属性NameをエンティティにマップしたいとしましょうUser。ユーザーが正確に 1 つの名前を持ち、各名前が正確に 1 人のユーザーに属していると仮定すると、このリンクは1 対 1 の関係を使用してアーカイブできます。

しかし、 と の関係をモデル化する方法attributevalue? 問題は、値の型が異なる場合や、情報を保存するために異なる数のフィールドが必要になる場合があることです。

name属性とを検討してくださいphone_number。名前は文字列で表すことができますが、電話番号には整数が必要になる場合があります。または、別のフィールドに番号だけでなく市外局番も必要です。

EAV は非常に柔軟な値表現を必要とするため、それらすべてをデータベース テーブルの同じフィールドに格納することはできません (ブロブやデータのシリアル化などは無視してください)。したがって、ほとんどの EAV 実装は、さまざまな値の型を表すさまざまなテーブルを使用しています。

このような柔軟性を実現するために、doctrine はInheritance Mappingを備えています。基本的に、ドクトリンエンティティを拡張できます。そうすることdiscriminatorで、エンティティのサブタイプごとにを指定します。

/**
  * @Entity
  * @InheritanceType("JOINED")
  * @DiscriminatorColumn(name="value_type", type="string")
  * @DiscriminatorMap({"name" = "Name", "phone" = "PhoneNumber"})
*/
class Value
{
// ...
}

/** @Entity */
class Name extends Value
{
// ...
}

/** @Entity */
class PhoneNumber extends Value
{
// ...
}

このValueクラスは、すべての値、つまり id に共通の実装を提供します。各サブクラス (つまりNamePhoneNumber) は、これらの共通の値を特定の値 (追加フィールドなど) で拡張します。

  • @DiscriminatorColumnは、値の型を格納する親リレーションの列を定義します。
  • は、型を からそれらのクラスの 1 つに@DiscriminatorMapマップするために教義によって使用されます。@DiscriminatorColumn

親クラスに との関係をattribute指定valueできます。属性から値を呼び出すと、たとえばinstanceofを使用して、実行時にフィルター処理 (および処理) できるすべてのタイプの値がフェッチされます。

于 2015-10-21T21:46:06.477 に答える