アプリケーションを作成し、モデルに ORM を使用することを計画していましたが、エンティティ属性値テーブルを使用するデータベースの一部があります。
私は Doctrine ORM がかなり気に入りましたが、実際に接続されているテーブルが EAV スタイルである場合、通常の教義エンティティのように見えるクラスを作成できるかどうかはわかりません。
これに Doctrine を使用することは可能でしょうか。
アプリケーションを作成し、モデルに ORM を使用することを計画していましたが、エンティティ属性値テーブルを使用するデータベースの一部があります。
私は Doctrine ORM がかなり気に入りましたが、実際に接続されているテーブルが EAV スタイルである場合、通常の教義エンティティのように見えるクラスを作成できるかどうかはわかりません。
これに Doctrine を使用することは可能でしょうか。
確実に可能:
次のような関係を持ちます: オブジェクト (1 対多) -> AttributeValue -> 多対 1 -> AttributeType
EAVの観点からすると、ドクトリンentity
とドクトリンの使用との間の関係を構築する方法は明らかであるように思われますattribute
。最も複雑なケースでは、多対多の関係を扱います。
それでは、属性Name
をエンティティにマップしたいとしましょうUser
。ユーザーが正確に 1 つの名前を持ち、各名前が正確に 1 人のユーザーに属していると仮定すると、このリンクは1 対 1 の関係を使用してアーカイブできます。
しかし、 と の関係をモデル化する方法attribute
はvalue
? 問題は、値の型が異なる場合や、情報を保存するために異なる数のフィールドが必要になる場合があることです。
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 に共通の実装を提供します。各サブクラス (つまりName
とPhoneNumber
) は、これらの共通の値を特定の値 (追加フィールドなど) で拡張します。
@DiscriminatorColumn
は、値の型を格納する親リレーションの列を定義します。@DiscriminatorMap
マップするために教義によって使用されます。@DiscriminatorColumn
親クラスに との関係をattribute
指定value
できます。属性から値を呼び出すと、たとえばinstanceofを使用して、実行時にフィルター処理 (および処理) できるすべてのタイプの値がフェッチされます。