21. XML Mapping¶
The XML mapping driver enables you to provide the ORM metadata in form of XML documents.
The XML driver is backed by an XML Schema document that describes the structure of a mapping document. The most recent version of the XML Schema document is available online at https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd. The most convenient way to work with XML mapping files is to use an IDE/editor that can provide code-completion based on such an XML Schema document. The following is an outline of a XML mapping document with the proper xmlns/xsi setup for the latest code in trunk.
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
...
</doctrine-mapping>
The XML mapping document of a class is loaded on-demand the first time it is requested and subsequently stored in the metadata cache. In order to work, this requires certain conventions:
Each entity/mapped superclass must get its own dedicated XML mapping document.
各エンティティ/マップされたスーパークラスは、専用の XML マッピング ドキュメントを取得する必要があります。The name of the mapping document must consist of the fully qualified name of the class, where namespace separators are replaced by dots (.). For example an Entity with the fully qualified class-name “MyProject” would require a mapping file “MyProject.Entities.User.dcm.xml” unless the extension is changed.
マッピング ドキュメントの名前は、クラスの完全修飾名で構成する必要があります。名前空間の区切り文字はドット (.) に置き換えられます。たとえば、拡張子が変更されない限り、完全修飾クラス名「MyProject」を持つエンティティには、マッピング ファイル「MyProject.Entities.User.dcm.xml」が必要です。All mapping documents should get the extension “.dcm.xml” to identify it as a Doctrine mapping file. This is more of a convention and you are not forced to do this. You can change the file extension easily enough.
Doctrine マッピング ファイルであることを識別するために、すべてのマッピング ドキュメントに拡張子「.dcm.xml」を付ける必要があります。これは慣習的なものであり、これを強制されるものではありません。ファイル拡張子は簡単に変更できます。
<?php
$driver->setFileExtension('.xml');
It is recommended to put all XML mapping documents in a single folder but you can spread the documents over several folders if you want to. In order to tell the XmlDriver where to look for your mapping documents, supply an array of paths as the first argument of the constructor, like this:
<?php
$config = new \Doctrine\ORM\Configuration();
$driver = new \Doctrine\ORM\Mapping\Driver\XmlDriver(array('/path/to/files1', '/path/to/files2'));
$config->setMetadataDriverImpl($driver);
Warning
Note that Doctrine ORM does not modify any settings for libxml
,
therefore, external XML entities may or may not be enabled or
configured correctly.
XML mappings are not XXE/XEE attack vectors since they are not
related with user input, but it is recommended that you do not
use external XML entities in your mapping files to avoid running
into unexpected behaviour.
21.1. Simplified XML Driver¶
The Symfony project sponsored a driver that simplifies usage of the XML Driver. The changes between the original driver are:
File Extension is .orm.xml
ファイル拡張子は .orm.xml ですFilenames are shortened, “MyProjectEntitiesUser” will become User.orm.xml
ファイル名は短縮され、「MyProjectEntitiesUser」は User.orm.xml になりますYou can add a global file and add multiple entities in this file.
グローバル ファイルを追加し、このファイルに複数のエンティティを追加できます。
Configuration of this client works a little bit different:
<?php
$namespaces = array(
'/path/to/files1' => 'MyProject\Entities',
'/path/to/files2' => 'OtherProject\Entities'
);
$driver = new \Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver($namespaces);
$driver->setGlobalBasename('global'); // global.orm.xml
21.1.1. Example¶
As a quick start, here is a small example document that makes use of several common elements:
// Doctrine.Tests.ORM.Mapping.User.dcm.xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
<indexes>
<index name="name_idx" columns="name"/>
<index columns="user_email"/>
</indexes>
<unique-constraints>
<unique-constraint columns="name,user_email" name="search_idx" />
</unique-constraints>
<lifecycle-callbacks>
<lifecycle-callback type="prePersist" method="doStuffOnPrePersist"/>
<lifecycle-callback type="prePersist" method="doOtherStuffOnPrePersistToo"/>
<lifecycle-callback type="postPersist" method="doStuffOnPostPersist"/>
</lifecycle-callbacks>
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
<sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
</id>
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
<one-to-one field="address" target-entity="Address" inversed-by="user">
<cascade><cascade-remove /></cascade>
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
</one-to-one>
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user">
<cascade>
<cascade-persist/>
</cascade>
<order-by>
<order-by-field name="number" direction="ASC" />
</order-by>
</one-to-many>
<many-to-many field="groups" target-entity="Group">
<cascade>
<cascade-all/>
</cascade>
<join-table name="cms_users_groups">
<join-columns>
<join-column name="user_id" referenced-column-name="id" nullable="false" unique="false" />
</join-columns>
<inverse-join-columns>
<join-column name="group_id" referenced-column-name="id" column-definition="INT NULL" />
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
</doctrine-mapping>
Be aware that class-names specified in the XML files should be fully qualified.
21.1.2. XML-Element Reference¶
The XML-Element reference explains all the tags and attributes that the Doctrine Mapping XSD Schema defines. You should read the Basic-, Association- and Inheritance Mapping chapters to understand what each of this definitions means in detail.
21.2. Defining an Entity¶
Each XML Mapping File contains the definition of one entity,
specified as the <entity />
element as a direct child of the
<doctrine-mapping />
element:
<doctrine-mapping>
<entity name="MyProject\User" table="cms_users" schema="schema_name" repository-class="MyProject\UserRepository">
<!-- definition here -->
</entity>
</doctrine-mapping>
Required attributes:
name - The fully qualified class-name of the entity.
name - エンティティの完全修飾クラス名。
Optional attributes:
table - The Table-Name to be used for this entity. Otherwise the Unqualified Class-Name is used by default.
table - このエンティティに使用されるテーブル名。それ以外の場合、非修飾クラス名がデフォルトで使用されます。repository-class - The fully qualified class-name of an alternative
Doctrine\ORM\EntityRepository
implementation to be used with this entity.repository-class - このエンティティで使用される別の Doctrine\ORM\EntityRepository 実装の完全修飾クラス名。inheritance-type - The type of inheritance, defaults to none. A more detailed description follows in the Defining Inheritance Mappings section.
inheritance-type - 継承のタイプで、デフォルトは none です。詳細な説明は、「継承マッピングの定義」セクションに続きます。read-only - Specifies that this entity is marked as read only and not considered for change-tracking. Entities of this type can be persisted and removed though.
読み取り専用 - このエンティティが読み取り専用としてマークされ、変更の追跡が考慮されないことを指定します。ただし、このタイプのエンティティは永続化および削除できます。schema - The schema the table lies in, for platforms that support schemas
schema - スキーマをサポートするプラットフォームの場合、テーブルがあるスキーマ
21.3. Defining Fields¶
Each entity class can contain zero to infinite fields that are
managed by Doctrine. You can define them using the <field />
element as a children to the <entity />
element. The field
element is only used for primitive types that are not the ID of the
entity. For the ID mapping you have to use the <id />
element.
<entity name="MyProject\User">
<field name="name" type="string" length="50" />
<field name="username" type="string" unique="true" />
<field name="age" type="integer" nullable="true" />
<field name="isActive" column="is_active" type="boolean" />
<field name="weight" type="decimal" scale="5" precision="2" />
<field name="login_count" type="integer" nullable="false">
<options>
<option name="comment">The number of times the user has logged in.</option>
<option name="default">0</option>
</options>
</field>
</entity>
Required attributes:
name - The name of the Property/Field on the given Entity PHP class.
name - 指定されたエンティティ PHPclass のプロパティ/フィールドの名前。
Optional attributes:
type - The
Doctrine\DBAL\Types\Type
name, defaults to “string”type - Doctrine\DBAL\Types\Type 名、デフォルトは「string」column - Name of the column in the database, defaults to the field name.
column - データベース内の列の名前。デフォルトはフィールド名です。length - The length of the given type, for use with strings only.
length - 文字列のみで使用する、指定された型の長さ。unique - Should this field contain a unique value across the table? Defaults to false.
unique - このフィールドには、テーブル全体で一意の値を含める必要がありますか?デフォルトは false です。nullable - Should this field allow NULL as a value? Defaults to false.
nullable - このフィールドは値として NULL を許可するか?デフォルトは false です。insertable - Should this field be inserted? Defaults to true.
insertable - このフィールドを挿入する必要がありますか?デフォルトは true です。updatable - Should this field be updated? Defaults to true.
updateable - このフィールドを更新する必要がありますか?デフォルトは true です。generated - Enum of the values ALWAYS, INSERT, NEVER that determines if generated value must be fetched from database after INSERT or UPDATE. Defaults to “NEVER”.
generated - INSERT または UPDATE の後に生成された値をデータベースから取得する必要があるかどうかを決定する ALWAYS、INSERT、NEVER の値の列挙。デフォルトは「NEVER」です。version - Should this field be used for optimistic locking? Only works on fields with type integer or datetime.
version - このフィールドを楽観的ロックに使用する必要がありますか?整数型または日時型のフィールドでのみ機能します。scale - Scale of a decimal type.
scale - 10 進数型のスケール。precision - Precision of a decimal type.
precision - 10 進数型の精度。options - Array of additional options:
options - 追加オプションの配列:default - The default value to set for the column if no value is supplied.
default - 値が指定されていない場合に列に設定するデフォルト値。unsigned - Boolean value to determine if the column should be capable of representing only non-negative integers (applies only for integer column and might not be supported by all vendors).
unsigned - 列が負でない整数のみを表すことができるかどうかを決定するブール値 (整数列にのみ適用され、すべてのベンダーでサポートされているとは限りません)。fixed - Boolean value to determine if the specified length of a string column should be fixed or varying (applies only for string/binary column and might not be supported by all vendors).
fixed - 文字列列の指定された長さが固定か可変かを決定するブール値 (文字列/バイナリ列にのみ適用され、すべてのベンダーでサポートされているわけではありません)。comment - The comment of the column in the schema (might not be supported by all vendors).
comment - スキーマ内の列のコメント (すべてのベンダーでサポートされているわけではありません)。customSchemaOptions - Array of additional schema options which are mostly vendor specific.
customSchemaOptions - ほとんどがベンダー固有の追加スキーマ オプションの配列。
column-definition - Optional alternative SQL representation for this column. This definition begin after the field-name and has to specify the complete column definition. Using this feature will turn this field dirty for Schema-Tool update commands at all times.
column-definition - この列のオプションの代替 SQL 表現。この定義はフィールド名の後に始まり、完全な列定義を指定する必要があります。この機能を使用すると、スキーマ ツールの更新コマンドに対して常にこのフィールドがダーティになります。
Note
For more detailed information on each attribute, please refer to
the DBAL Schema-Representation
documentation.
21.4. Defining Identity and Generator Strategies¶
An entity has to have at least one <id />
element. For
composite keys you can specify more than one id-element, however
surrogate keys are recommended for use with Doctrine ORM. The Id
field allows to define properties of the identifier and allows a
subset of the <field />
element attributes:
<entity name="MyProject\User">
<id name="id" type="integer" column="user_id" />
</entity>
Required attributes:
name - The name of the Property/Field on the given Entity PHP class.
name - 指定されたエンティティ PHPclass のプロパティ/フィールドの名前。type - The
Doctrine\DBAL\Types\Type
name, preferably “string” or “integer”.type - Doctrine\DBAL\Types\Type 名、できれば「文字列」または「整数」。
Optional attributes:
column - Name of the column in the database, defaults to the field name.
column - データベース内の列の名前。デフォルトはフィールド名です。
Using the simplified definition above Doctrine will use no
identifier strategy for this entity. That means you have to
manually set the identifier before calling
EntityManager#persist($entity)
. This is the so called
NONE
strategy.
If you want to switch the identifier generation strategy you have
to nest a <generator />
element inside the id-element. This of
course only works for surrogate keys. For composite keys you always
have to use the NONE
strategy.
<entity name="MyProject\User">
<id name="id" type="integer" column="user_id">
<generator strategy="AUTO" />
</id>
</entity>
The following values are allowed for the <generator />
strategy
attribute:
AUTO - Automatic detection of the identifier strategy based on the preferred solution of the database vendor.
AUTO - データベース ベンダーの推奨ソリューションに基づく識別子戦略の自動検出。IDENTITY - Use of a IDENTIFY strategy such as Auto-Increment IDs available to Doctrine AFTER the INSERT statement has been executed.
IDENTITY - INSERT ステートメントが実行された後、Doctrine で利用可能な自動インクリメント ID などの IDENTIFY 戦略の使用。SEQUENCE - Use of a database sequence to retrieve the entity-ids. This is possible before the INSERT statement is executed.
SEQUENCE - エンティティ ID を取得するためのデータベース シーケンスの使用。これは、INSERT ステートメントが実行される前に可能です。
If you are using the SEQUENCE strategy you can define an additional element to describe the sequence:
<entity name="MyProject\User">
<id name="id" type="integer" column="user_id">
<generator strategy="SEQUENCE" />
<sequence-generator sequence-name="user_seq" allocation-size="5" initial-value="1" />
</id>
</entity>
Required attributes for <sequence-generator />
:
sequence-name - The name of the sequence
sequence-name - シーケンスの名前
Optional attributes for <sequence-generator />
:
allocation-size - By how much steps should the sequence be incremented when a value is retrieved. Defaults to 1
割り当てサイズ - 値を取得するときにシーケンスをインクリメントするステップ数。デフォルトは 1initial-value - What should the initial value of the sequence be.
initial-value - シーケンスの初期値。NOTE
ノートIf you want to implement a cross-vendor compatible application you have to specify and additionally define the <sequence-generator /> element, if Doctrine chooses the sequence strategy for a platform.
ベンダー間で互換性のあるアプリケーションを実装したい場合、Doctrine がプラットフォームのシーケンス戦略を選択する場合、要素を指定して追加で定義する必要があります。
21.5. Defining a Mapped Superclass¶
Sometimes you want to define a class that multiple entities inherit
from, which itself is not an entity however. The chapter on
Inheritance Mapping describes a Mapped Superclass in detail. You
can define it in XML using the <mapped-superclass />
tag.
<doctrine-mapping>
<mapped-superclass name="MyProject\BaseClass">
<field name="created" type="datetime" />
<field name="updated" type="datetime" />
</mapped-superclass>
</doctrine-mapping>
Required attributes:
name - Class name of the mapped superclass.
name - マップされたスーパークラスのクラス名。
You can nest any number of <field />
and unidirectional
<many-to-one />
or <one-to-one />
associations inside a
mapped superclass.
21.6. Defining Inheritance Mappings¶
There are currently two inheritance persistence strategies that you can choose from when defining entities that inherit from each other. Single Table inheritance saves the fields of the complete inheritance hierarchy in a single table, joined table inheritance creates a table for each entity combining the fields using join conditions.
You can specify the inheritance type in the <entity />
element
and then use the <discriminator-column />
and
<discriminator-mapping />
attributes.
<entity name="MyProject\Animal" inheritance-type="JOINED">
<discriminator-column name="discr" type="string" />
<discriminator-map>
<discriminator-mapping value="cat" class="MyProject\Cat" />
<discriminator-mapping value="dog" class="MyProject\Dog" />
<discriminator-mapping value="mouse" class="MyProject\Mouse" />
</discriminator-map>
</entity>
The allowed values for inheritance-type attribute are JOINED
or
SINGLE_TABLE
.
Note
All inheritance related definitions have to be defined on the root entity of the hierarchy.
21.7. Defining Lifecycle Callbacks¶
You can define the lifecycle callback methods on your entities
using the <lifecycle-callbacks />
element:
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
<lifecycle-callbacks>
<lifecycle-callback type="prePersist" method="onPrePersist" />
</lifecycle-callbacks>
</entity>
21.8. Defining One-To-One Relations¶
You can define One-To-One Relations/Associations using the
<one-to-one />
element. The required and optional attributes
depend on the associations being on the inverse or owning side.
For the inverse side the mapping is as simple as:
<entity class="MyProject\User">
<one-to-one field="address" target-entity="Address" mapped-by="user" />
</entity>
Required attributes for inverse One-To-One:
field - Name of the property/field on the entity’s PHP class.
field - エンティティの PHP クラスのプロパティ/フィールドの名前。target-entity - Name of the entity associated entity class. If this is not qualified the namespace of the current class is prepended. IMPORTANT: No leading backslash!
target-entity - エンティティに関連付けられたエンティティ クラスの名前。これが修飾されていない場合、現在のクラスの名前空間が先頭に追加されます。重要: 先頭にバックスラッシュはありません!mapped-by - Name of the field on the owning side (here Address entity) that contains the owning side association.
maps-by - 所有側の関連付けを含む所有側 (ここでは Addressentity) のフィールドの名前。
For the owning side this mapping would look like:
<entity class="MyProject\Address">
<one-to-one field="user" target-entity="User" inversed-by="address" />
</entity>
Required attributes for owning One-to-One:
field - Name of the property/field on the entity’s PHP class.
field - エンティティの PHP クラスのプロパティ/フィールドの名前。target-entity - Name of the entity associated entity class. If this is not qualified the namespace of the current class is prepended. IMPORTANT: No leading backslash!
target-entity - エンティティに関連付けられたエンティティ クラスの名前。これが修飾されていない場合、現在のクラスの名前空間が先頭に追加されます。重要: 先頭にバックスラッシュはありません!
Optional attributes for owning One-to-One:
inversed-by - If the association is bidirectional the inversed-by attribute has to be specified with the name of the field on the inverse entity that contains the back-reference.
inversed-by - アソシエーションが双方向の場合、逆参照を含む逆エンティティのフィールドの名前で inversed-by 属性を指定する必要があります。orphan-removal - If true, the inverse side entity is always deleted when the owning side entity is. Defaults to false.
orphan-removal - true の場合、所有側エンティティが削除されると、逆側エンティティは常に削除されます。デフォルトは false です。fetch - Either LAZY or EAGER, defaults to LAZY. This attribute makes only sense on the owning side, the inverse side ALWAYS has to use the
FETCH
strategy.fetch - LAZY または EAGER のいずれかで、デフォルトは LAZY です。この属性は、所有側でのみ意味を持ち、逆側では常に FETCH 戦略を使用する必要があります。
The definition for the owning side relies on a bunch of mapping
defaults for the join column names. Without the nested
<join-column />
element Doctrine assumes to foreign key to be
called user_id
on the Address Entities table. This is because
the MyProject\Address
entity is the owning side of this
association, which means it contains the foreign key.
The completed explicitly defined mapping is:
<entity class="MyProject\Address">
<one-to-one field="user" target-entity="User" inversed-by="address">
<join-column name="user_id" referenced-column-name="id" />
</one-to-one>
</entity>
21.9. Defining Many-To-One Associations¶
The many-to-one association is ALWAYS the owning side of any bidirectional association. This simplifies the mapping compared to the one-to-one case. The minimal mapping for this association looks like:
<entity class="MyProject\Article">
<many-to-one field="author" target-entity="User" />
</entity>
Required attributes:
field - Name of the property/field on the entity’s PHP class.
field - エンティティの PHP クラスのプロパティ/フィールドの名前。target-entity - Name of the entity associated entity class. If this is not qualified the namespace of the current class is prepended. IMPORTANT: No leading backslash!
target-entity - エンティティに関連付けられたエンティティ クラスの名前。これが修飾されていない場合、現在のクラスの名前空間が先頭に追加されます。重要: 先頭にバックスラッシュはありません!
Optional attributes:
inversed-by - If the association is bidirectional the inversed-by attribute has to be specified with the name of the field on the inverse entity that contains the back-reference.
inversed-by - アソシエーションが双方向の場合、逆参照を含む逆エンティティのフィールドの名前で inversed-by 属性を指定する必要があります。orphan-removal - If true the entity on the inverse side is always deleted when the owning side entity is and it is not connected to any other owning side entity anymore. Defaults to false.
orphan-removal - true の場合、所有側エンティティが他の所有側エンティティに接続されていない場合、反対側のエンティティは常に削除されます。デフォルトは false です。fetch - Either LAZY or EAGER, defaults to LAZY.
fetch - LAZY または EAGER のいずれかで、デフォルトは LAZY です。
This definition relies on a bunch of mapping defaults with regards
to the naming of the join-column/foreign key. The explicitly
defined mapping includes a <join-column />
tag nested inside
the many-to-one association tag:
<entity class="MyProject\Article">
<many-to-one field="author" target-entity="User">
<join-column name="author_id" referenced-column-name="id" />
</many-to-one>
</entity>
The join-column attribute name
specifies the column name of the
foreign key and the referenced-column-name
attribute specifies
the name of the primary key column on the User entity.
21.10. Defining One-To-Many Associations¶
The one-to-many association is ALWAYS the inverse side of any association. There exists no such thing as a uni-directional one-to-many association, which means this association only ever exists for bi-directional associations.
<entity class="MyProject\User">
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user" />
</entity>
Required attributes:
field - Name of the property/field on the entity’s PHP class.
field - エンティティの PHP クラスのプロパティ/フィールドの名前。target-entity - Name of the entity associated entity class. If this is not qualified the namespace of the current class is prepended. IMPORTANT: No leading backslash!
target-entity - エンティティに関連付けられたエンティティ クラスの名前。これが修飾されていない場合、現在のクラスの名前空間が先頭に追加されます。重要: 先頭にバックスラッシュはありません!mapped-by - Name of the field on the owning side (here Phonenumber entity) that contains the owning side association.
mapping-by - 所有側の関連付けを含む所有側 (herePhonenumber エンティティ) のフィールドの名前。
Optional attributes:
fetch - Either LAZY, EXTRA_LAZY or EAGER, defaults to LAZY.
fetch - LAZY、EXTRA_LAZY、または EAGER のいずれかで、デフォルトは LAZY です。index-by: Index the collection by a field on the target entity.
index-by: ターゲット エンティティのフィールドによってコレクションにインデックスを付けます。
21.11. Defining Many-To-Many Associations¶
From all the associations the many-to-many has the most complex definition. When you rely on the mapping defaults you can omit many definitions and rely on their implicit values.
<entity class="MyProject\User">
<many-to-many field="groups" target-entity="Group" />
</entity>
Required attributes:
field - Name of the property/field on the entity’s PHP class.
field - エンティティの PHP クラスのプロパティ/フィールドの名前。target-entity - Name of the entity associated entity class. If this is not qualified the namespace of the current class is prepended. IMPORTANT: No leading backslash!
target-entity - エンティティに関連付けられたエンティティ クラスの名前。これが修飾されていない場合、現在のクラスの名前空間が先頭に追加されます。重要: 先頭にバックスラッシュはありません!
Optional attributes:
mapped-by - Name of the field on the owning side that contains the owning side association if the defined many-to-many association is on the inverse side.
mapping-by - 定義された多対多の関連付けが逆側にある場合、所有側の関連付けを含む所有側のフィールドの名前。inversed-by - If the association is bidirectional the inversed-by attribute has to be specified with the name of the field on the inverse entity that contains the back-reference.
inversed-by - アソシエーションが双方向の場合、逆参照を含む逆エンティティのフィールドの名前で inversed-by 属性を指定する必要があります。fetch - Either LAZY, EXTRA_LAZY or EAGER, defaults to LAZY.
fetch - LAZY、EXTRA_LAZY、または EAGER のいずれかで、デフォルトは LAZY です。index-by: Index the collection by a field on the target entity.
index-by: ターゲット エンティティのフィールドによってコレクションにインデックスを付けます。
The mapping defaults would lead to a join-table with the name “User_Group” being created that contains two columns “user_id” and “group_id”. The explicit definition of this mapping would be:
<entity class="MyProject\User">
<many-to-many field="groups" target-entity="Group">
<join-table name="cms_users_groups">
<join-columns>
<join-column name="user_id" referenced-column-name="id"/>
</join-columns>
<inverse-join-columns>
<join-column name="group_id" referenced-column-name="id"/>
</inverse-join-columns>
</join-table>
</many-to-many>
</entity>
Here both the <join-columns>
and <inverse-join-columns>
tags are necessary to tell Doctrine for which side the specified
join-columns apply. These are nested inside a <join-table />
attribute which allows to specify the table name of the
many-to-many join-table.
21.12. Cascade Element¶
Doctrine allows cascading of several UnitOfWork operations to
related entities. You can specify the cascade operations in the
<cascade />
element inside any of the association mapping
tags.
<entity class="MyProject\User">
<many-to-many field="groups" target-entity="Group">
<cascade>
<cascade-all/>
</cascade>
</many-to-many>
</entity>
Besides <cascade-all />
the following operations can be
specified by their respective tags:
<cascade-persist />
<cascade-merge />
<cascade-remove />
<cascade-refresh />
<cascade-detach />
21.13. Join Column Element¶
In any explicitly defined association mapping you will need the
<join-column />
tag. It defines how the foreign key and primary
key names are called that are used for joining two entities.
Required attributes:
name - The column name of the foreign key.
name - 外部キーの列名。referenced-column-name - The column name of the associated entities primary key
referenced-column-name - associatedentities 主キーの列名
Optional attributes:
unique - If the join column should contain a UNIQUE constraint. This makes sense for Many-To-Many join-columns only to simulate a one-to-many unidirectional using a join-table.
unique - 結合列に UNIQUE 制約を含める必要がある場合。これは、結合テーブルを使用して 1 対多の一方向をシミュレートするためにのみ、多対多の結合列に意味があります。nullable - should the join column be nullable, defaults to true.
nullable - 結合列が null 可能である必要があります。デフォルトは true です。on-delete - Foreign Key Cascade action to perform when entity is deleted, defaults to NO ACTION/RESTRICT but can be set to “CASCADE”.
on-delete - エンティティが削除されたときに実行する外部キー カスケード アクション。デフォルトは NO ACTION/RESTRICT ですが、「CASCADE」に設定できます。
21.14. Defining Order of To-Many Associations¶
You can require one-to-many or many-to-many associations to be
retrieved using an additional ORDER BY
.
<entity class="MyProject\User">
<many-to-many field="groups" target-entity="Group">
<order-by>
<order-by-field name="name" direction="ASC" />
</order-by>
</many-to-many>
</entity>
21.15. Defining Indexes or Unique Constraints¶
To define additional indexes or unique constraints on the entities
table you can use the <indexes />
and
<unique-constraints />
elements:
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
<indexes>
<index name="name_idx" columns="name"/>
<index columns="user_email"/>
</indexes>
<unique-constraints>
<unique-constraint columns="name,user_email" name="search_idx" />
</unique-constraints>
</entity>
You have to specify the column and not the entity-class field names in the index and unique-constraint definitions.
21.16. Derived Entities ID syntax¶
If the primary key of an entity contains a foreign key to another entity we speak of a derived
entity relationship. You can define this in XML with the “association-key” attribute in the <id>
tag.
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Application\Model\ArticleAttribute">
<id name="article" association-key="true" />
<id name="attribute" type="string" />
<field name="value" type="string" />
<many-to-one field="article" target-entity="Article" inversed-by="attributes" />
</entity>
</doctrine-mapping>