basic-mapping.rst 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. Basic Mapping
  2. =============
  3. This chapter explains the basic mapping of objects and properties.
  4. Mapping of associations will be covered in the next chapter
  5. "Association Mapping".
  6. Mapping Drivers
  7. ---------------
  8. Doctrine provides several different ways for specifying
  9. object-relational mapping metadata:
  10. - Docblock Annotations
  11. - XML
  12. - YAML
  13. This manual usually mentions docblock annotations in all the examples
  14. that are spread throughout all chapters, however for many examples
  15. alternative YAML and XML examples are given as well. There are dedicated
  16. reference chapters for XML and YAML mapping, respectively that explain them
  17. in more detail. There is also an Annotation reference chapter.
  18. .. note::
  19. If you're wondering which mapping driver gives the best
  20. performance, the answer is: They all give exactly the same performance.
  21. Once the metadata of a class has
  22. been read from the source (annotations, xml or yaml) it is stored
  23. in an instance of the ``Doctrine\ORM\Mapping\ClassMetadata`` class
  24. and these instances are stored in the metadata cache. Therefore at
  25. the end of the day all drivers perform equally well. If you're not
  26. using a metadata cache (not recommended!) then the XML driver might
  27. have a slight edge in performance due to the powerful native XML
  28. support in PHP.
  29. Introduction to Docblock Annotations
  30. ------------------------------------
  31. You've probably used docblock annotations in some form already,
  32. most likely to provide documentation metadata for a tool like
  33. ``PHPDocumentor`` (@author, @link, ...). Docblock annotations are a
  34. tool to embed metadata inside the documentation section which can
  35. then be processed by some tool. Doctrine 2 generalizes the concept
  36. of docblock annotations so that they can be used for any kind of
  37. metadata and so that it is easy to define new docblock annotations.
  38. In order to allow more involved annotation values and to reduce the
  39. chances of clashes with other docblock annotations, the Doctrine 2
  40. docblock annotations feature an alternative syntax that is heavily
  41. inspired by the Annotation syntax introduced in Java 5.
  42. The implementation of these enhanced docblock annotations is
  43. located in the ``Doctrine\Common\Annotations`` namespace and
  44. therefore part of the Common package. Doctrine 2 docblock
  45. annotations support namespaces and nested annotations among other
  46. things. The Doctrine 2 ORM defines its own set of docblock
  47. annotations for supplying object-relational mapping metadata.
  48. .. note::
  49. If you're not comfortable with the concept of docblock
  50. annotations, don't worry, as mentioned earlier Doctrine 2 provides
  51. XML and YAML alternatives and you could easily implement your own
  52. favourite mechanism for defining ORM metadata.
  53. Persistent classes
  54. ------------------
  55. In order to mark a class for object-relational persistence it needs
  56. to be designated as an entity. This can be done through the
  57. ``@Entity`` marker annotation.
  58. .. configuration-block::
  59. .. code-block:: php
  60. <?php
  61. /** @Entity */
  62. class MyPersistentClass
  63. {
  64. //...
  65. }
  66. .. code-block:: xml
  67. <doctrine-mapping>
  68. <entity name="MyPersistentClass">
  69. <!-- ... -->
  70. </entity>
  71. </doctrine-mapping>
  72. .. code-block:: yaml
  73. MyPersistentClass:
  74. type: entity
  75. # ...
  76. By default, the entity will be persisted to a table with the same
  77. name as the class name. In order to change that, you can use the
  78. ``@Table`` annotation as follows:
  79. .. configuration-block::
  80. .. code-block:: php
  81. <?php
  82. /**
  83. * @Entity
  84. * @Table(name="my_persistent_class")
  85. */
  86. class MyPersistentClass
  87. {
  88. //...
  89. }
  90. .. code-block:: xml
  91. <doctrine-mapping>
  92. <entity name="MyPersistentClass" table="my_persistent_class">
  93. <!-- ... -->
  94. </entity>
  95. </doctrine-mapping>
  96. .. code-block:: yaml
  97. MyPersistentClass:
  98. type: entity
  99. table: my_persistent_class
  100. # ...
  101. Now instances of MyPersistentClass will be persisted into a table
  102. named ``my_persistent_class``.
  103. Doctrine Mapping Types
  104. ----------------------
  105. A Doctrine Mapping Type defines the mapping between a PHP type and
  106. a SQL type. All Doctrine Mapping Types that ship with Doctrine are
  107. fully portable between different RDBMS. You can even write your own
  108. custom mapping types that might or might not be portable, which is
  109. explained later in this chapter.
  110. For example, the Doctrine Mapping Type ``string`` defines the
  111. mapping from a PHP string to a SQL VARCHAR (or VARCHAR2 etc.
  112. depending on the RDBMS brand). Here is a quick overview of the
  113. built-in mapping types:
  114. - ``string``: Type that maps a SQL VARCHAR to a PHP string.
  115. - ``integer``: Type that maps a SQL INT to a PHP integer.
  116. - ``smallint``: Type that maps a database SMALLINT to a PHP
  117. integer.
  118. - ``bigint``: Type that maps a database BIGINT to a PHP string.
  119. - ``boolean``: Type that maps a SQL boolean to a PHP boolean.
  120. - ``decimal``: Type that maps a SQL DECIMAL to a PHP string.
  121. - ``date``: Type that maps a SQL DATETIME to a PHP DateTime
  122. object.
  123. - ``time``: Type that maps a SQL TIME to a PHP DateTime object.
  124. - ``datetime``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP
  125. DateTime object.
  126. - ``datetimetz``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP
  127. DateTime object with timezone.
  128. - ``text``: Type that maps a SQL CLOB to a PHP string.
  129. - ``object``: Type that maps a SQL CLOB to a PHP object using
  130. ``serialize()`` and ``unserialize()``
  131. - ``array``: Type that maps a SQL CLOB to a PHP array using
  132. ``serialize()`` and ``unserialize()``
  133. - ``simple_array``: Type that maps a SQL CLOB to a PHP array using
  134. ``implode()`` and ``explode()``, with a comma as delimiter. *IMPORTANT*
  135. Only use this type if you are sure that your values cannot contain a ",".
  136. - ``json_array``: Type that maps a SQL CLOB to a PHP array using
  137. ``json_encode()`` and ``json_decode()``
  138. - ``float``: Type that maps a SQL Float (Double Precision) to a
  139. PHP double. *IMPORTANT*: Works only with locale settings that use
  140. decimal points as separator.
  141. - ``guid``: Type that maps a database GUID/UUID to a PHP string. Defaults to
  142. varchar but uses a specific type if the platform supports it.
  143. - ``blob``: Type that maps a SQL BLOB to a PHP resource stream
  144. .. note::
  145. Doctrine Mapping Types are NOT SQL types and NOT PHP
  146. types! They are mapping types between 2 types.
  147. Additionally Mapping types are *case-sensitive*. For example, using
  148. a DateTime column will NOT match the datetime type that ships with
  149. Doctrine 2.
  150. .. note::
  151. DateTime and Object types are compared by reference, not by value. Doctrine updates this values
  152. if the reference changes and therefore behaves as if these objects are immutable value objects.
  153. .. warning::
  154. All Date types assume that you are exclusively using the default timezone
  155. set by `date_default_timezone_set() <http://docs.php.net/manual/en/function.date-default-timezone-set.php>`_
  156. or by the php.ini configuration ``date.timezone``. Working with
  157. different timezones will cause troubles and unexpected behavior.
  158. If you need specific timezone handling you have to handle this
  159. in your domain, converting all the values back and forth from UTC.
  160. There is also a :doc:`cookbook entry <../cookbook/working-with-datetime>`
  161. on working with datetimes that gives hints for implementing
  162. multi timezone applications.
  163. Property Mapping
  164. ----------------
  165. After a class has been marked as an entity it can specify mappings
  166. for its instance fields. Here we will only look at simple fields
  167. that hold scalar values like strings, numbers, etc. Associations to
  168. other objects are covered in the chapter "Association Mapping".
  169. To mark a property for relational persistence the ``@Column``
  170. docblock annotation is used. This annotation usually requires at
  171. least 1 attribute to be set, the ``type``. The ``type`` attribute
  172. specifies the Doctrine Mapping Type to use for the field. If the
  173. type is not specified, 'string' is used as the default mapping type
  174. since it is the most flexible.
  175. Example:
  176. .. configuration-block::
  177. .. code-block:: php
  178. <?php
  179. /** @Entity */
  180. class MyPersistentClass
  181. {
  182. /** @Column(type="integer") */
  183. private $id;
  184. /** @Column(length=50) */
  185. private $name; // type defaults to string
  186. //...
  187. }
  188. .. code-block:: xml
  189. <doctrine-mapping>
  190. <entity name="MyPersistentClass">
  191. <field name="id" type="integer" />
  192. <field name="name" length="50" />
  193. </entity>
  194. </doctrine-mapping>
  195. .. code-block:: yaml
  196. MyPersistentClass:
  197. type: entity
  198. fields:
  199. id:
  200. type: integer
  201. name:
  202. length: 50
  203. In that example we mapped the field ``id`` to the column ``id``
  204. using the mapping type ``integer`` and the field ``name`` is mapped
  205. to the column ``name`` with the default mapping type ``string``. As
  206. you can see, by default the column names are assumed to be the same
  207. as the field names. To specify a different name for the column, you
  208. can use the ``name`` attribute of the Column annotation as
  209. follows:
  210. .. configuration-block::
  211. .. code-block:: php
  212. <?php
  213. /** @Column(name="db_name") */
  214. private $name;
  215. .. code-block:: xml
  216. <doctrine-mapping>
  217. <entity name="MyPersistentClass">
  218. <field name="name" column="db_name" />
  219. </entity>
  220. </doctrine-mapping>
  221. .. code-block:: yaml
  222. MyPersistentClass:
  223. type: entity
  224. fields:
  225. name:
  226. length: 50
  227. column: db_name
  228. The Column annotation has some more attributes. Here is a complete
  229. list:
  230. - ``type``: (optional, defaults to 'string') The mapping type to
  231. use for the column.
  232. - ``column``: (optional, defaults to field name) The name of the
  233. column in the database.
  234. - ``length``: (optional, default 255) The length of the column in
  235. the database. (Applies only if a string-valued column is used).
  236. - ``unique``: (optional, default FALSE) Whether the column is a
  237. unique key.
  238. - ``nullable``: (optional, default FALSE) Whether the database
  239. column is nullable.
  240. - ``precision``: (optional, default 0) The precision for a decimal
  241. (exact numeric) column. (Applies only if a decimal column is used.)
  242. - ``scale``: (optional, default 0) The scale for a decimal (exact
  243. numeric) column. (Applies only if a decimal column is used.)
  244. .. _reference-basic-mapping-custom-mapping-types:
  245. Custom Mapping Types
  246. --------------------
  247. Doctrine allows you to create new mapping types. This can come in
  248. handy when you're missing a specific mapping type or when you want
  249. to replace the existing implementation of a mapping type.
  250. In order to create a new mapping type you need to subclass
  251. ``Doctrine\DBAL\Types\Type`` and implement/override the methods as
  252. you wish. Here is an example skeleton of such a custom type class:
  253. .. code-block:: php
  254. <?php
  255. namespace My\Project\Types;
  256. use Doctrine\DBAL\Types\Type;
  257. use Doctrine\DBAL\Platforms\AbstractPlatform;
  258. /**
  259. * My custom datatype.
  260. */
  261. class MyType extends Type
  262. {
  263. const MYTYPE = 'mytype'; // modify to match your type name
  264. public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
  265. {
  266. // return the SQL used to create your column type. To create a portable column type, use the $platform.
  267. }
  268. public function convertToPHPValue($value, AbstractPlatform $platform)
  269. {
  270. // This is executed when the value is read from the database. Make your conversions here, optionally using the $platform.
  271. }
  272. public function convertToDatabaseValue($value, AbstractPlatform $platform)
  273. {
  274. // This is executed when the value is written to the database. Make your conversions here, optionally using the $platform.
  275. }
  276. public function getName()
  277. {
  278. return self::MYTYPE; // modify to match your constant name
  279. }
  280. }
  281. Restrictions to keep in mind:
  282. - If the value of the field is *NULL* the method
  283. ``convertToDatabaseValue()`` is not called.
  284. - The ``UnitOfWork`` never passes values to the database convert
  285. method that did not change in the request.
  286. When you have implemented the type you still need to let Doctrine
  287. know about it. This can be achieved through the
  288. ``Doctrine\DBAL\Types\Type#addType($name, $className)``
  289. method. See the following example:
  290. .. code-block:: php
  291. <?php
  292. // in bootstrapping code
  293. // ...
  294. use Doctrine\DBAL\Types\Type;
  295. // ...
  296. // Register my type
  297. Type::addType('mytype', 'My\Project\Types\MyType');
  298. As can be seen above, when registering the custom types in the
  299. configuration you specify a unique name for the mapping type and
  300. map that to the corresponding fully qualified class name. Now you
  301. can use your new type in your mapping like this:
  302. .. code-block:: php
  303. <?php
  304. class MyPersistentClass
  305. {
  306. /** @Column(type="mytype") */
  307. private $field;
  308. }
  309. To have Schema-Tool convert the underlying database type of your
  310. new "mytype" directly into an instance of ``MyType`` you have to
  311. additionally register this mapping with your database platform:
  312. .. code-block:: php
  313. <?php
  314. $conn = $em->getConnection();
  315. $conn->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype');
  316. Now using Schema-Tool, whenever it detects a column having the
  317. ``db_mytype`` it will convert it into a ``mytype`` Doctrine Type
  318. instance for Schema representation. Keep in mind that you can
  319. easily produce clashes this way, each database type can only map to
  320. exactly one Doctrine mapping type.
  321. Custom ColumnDefinition
  322. -----------------------
  323. You can define a custom definition for each column using the "columnDefinition"
  324. attribute of ``@Column``. You have to define all the definitions that follow
  325. the name of a column here.
  326. .. note::
  327. Using columnDefinition will break change-detection in SchemaTool.
  328. Identifiers / Primary Keys
  329. --------------------------
  330. Every entity class needs an identifier/primary key. You designate
  331. the field that serves as the identifier with the ``@Id`` marker
  332. annotation. Here is an example:
  333. .. configuration-block::
  334. .. code-block:: php
  335. <?php
  336. class MyPersistentClass
  337. {
  338. /** @Id @Column(type="integer") */
  339. private $id;
  340. //...
  341. }
  342. .. code-block:: xml
  343. <doctrine-mapping>
  344. <entity name="MyPersistentClass">
  345. <id name="id" type="integer" />
  346. <field name="name" length="50" />
  347. </entity>
  348. </doctrine-mapping>
  349. .. code-block:: yaml
  350. MyPersistentClass:
  351. type: entity
  352. id:
  353. id:
  354. type: integer
  355. fields:
  356. name:
  357. length: 50
  358. Without doing anything else, the identifier is assumed to be
  359. manually assigned. That means your code would need to properly set
  360. the identifier property before passing a new entity to
  361. ``EntityManager#persist($entity)``.
  362. A common alternative strategy is to use a generated value as the
  363. identifier. To do this, you use the ``@GeneratedValue`` annotation
  364. like this:
  365. .. configuration-block::
  366. .. code-block:: php
  367. <?php
  368. class MyPersistentClass
  369. {
  370. /**
  371. * @Id @Column(type="integer")
  372. * @GeneratedValue
  373. */
  374. private $id;
  375. }
  376. .. code-block:: xml
  377. <doctrine-mapping>
  378. <entity name="MyPersistentClass">
  379. <id name="id" type="integer">
  380. <generator strategy="AUTO" />
  381. </id>
  382. <field name="name" length="50" />
  383. </entity>
  384. </doctrine-mapping>
  385. .. code-block:: yaml
  386. MyPersistentClass:
  387. type: entity
  388. id:
  389. id:
  390. type: integer
  391. generator:
  392. strategy: AUTO
  393. fields:
  394. name:
  395. length: 50
  396. This tells Doctrine to automatically generate a value for the
  397. identifier. How this value is generated is specified by the
  398. ``strategy`` attribute, which is optional and defaults to 'AUTO'. A
  399. value of ``AUTO`` tells Doctrine to use the generation strategy
  400. that is preferred by the currently used database platform. See
  401. below for details.
  402. Identifier Generation Strategies
  403. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  404. The previous example showed how to use the default identifier
  405. generation strategy without knowing the underlying database with
  406. the AUTO-detection strategy. It is also possible to specify the
  407. identifier generation strategy more explicitly, which allows to
  408. make use of some additional features.
  409. Here is the list of possible generation strategies:
  410. - ``AUTO`` (default): Tells Doctrine to pick the strategy that is
  411. preferred by the used database platform. The preferred strategies
  412. are IDENTITY for MySQL, SQLite and MsSQL and SEQUENCE for Oracle
  413. and PostgreSQL. This strategy provides full portability.
  414. - ``SEQUENCE``: Tells Doctrine to use a database sequence for ID
  415. generation. This strategy does currently not provide full
  416. portability. Sequences are supported by Oracle and PostgreSql.
  417. - ``IDENTITY``: Tells Doctrine to use special identity columns in
  418. the database that generate a value on insertion of a row. This
  419. strategy does currently not provide full portability and is
  420. supported by the following platforms: MySQL/SQLite
  421. (AUTO\_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL).
  422. - ``TABLE``: Tells Doctrine to use a separate table for ID
  423. generation. This strategy provides full portability.
  424. ***This strategy is not yet implemented!***
  425. - ``NONE``: Tells Doctrine that the identifiers are assigned (and
  426. thus generated) by your code. The assignment must take place before
  427. a new entity is passed to ``EntityManager#persist``. NONE is the
  428. same as leaving off the @GeneratedValue entirely.
  429. Sequence Generator
  430. ^^^^^^^^^^^^^^^^^^
  431. The Sequence Generator can currently be used in conjunction with
  432. Oracle or Postgres and allows some additional configuration options
  433. besides specifying the sequence's name:
  434. .. configuration-block::
  435. .. code-block:: php
  436. <?php
  437. class User
  438. {
  439. /**
  440. * @Id
  441. * @GeneratedValue(strategy="SEQUENCE")
  442. * @SequenceGenerator(sequenceName="tablename_seq", initialValue=1, allocationSize=100)
  443. */
  444. protected $id = null;
  445. }
  446. .. code-block:: xml
  447. <doctrine-mapping>
  448. <entity name="User">
  449. <id name="id" type="integer">
  450. <generator strategy="SEQUENCE" />
  451. <sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
  452. </id>
  453. </entity>
  454. </doctrine-mapping>
  455. .. code-block:: yaml
  456. MyPersistentClass:
  457. type: entity
  458. id:
  459. id:
  460. type: integer
  461. generator:
  462. strategy: SEQUENCE
  463. sequenceGenerator:
  464. sequenceName: tablename_seq
  465. allocationSize: 100
  466. initialValue: 1
  467. The initial value specifies at which value the sequence should
  468. start.
  469. The allocationSize is a powerful feature to optimize INSERT
  470. performance of Doctrine. The allocationSize specifies by how much
  471. values the sequence is incremented whenever the next value is
  472. retrieved. If this is larger than 1 (one) Doctrine can generate
  473. identifier values for the allocationSizes amount of entities. In
  474. the above example with ``allocationSize=100`` Doctrine 2 would only
  475. need to access the sequence once to generate the identifiers for
  476. 100 new entities.
  477. *The default allocationSize for a @SequenceGenerator is currently 10.*
  478. .. caution::
  479. The allocationSize is detected by SchemaTool and
  480. transformed into an "INCREMENT BY " clause in the CREATE SEQUENCE
  481. statement. For a database schema created manually (and not
  482. SchemaTool) you have to make sure that the allocationSize
  483. configuration option is never larger than the actual sequences
  484. INCREMENT BY value, otherwise you may get duplicate keys.
  485. .. note::
  486. It is possible to use strategy="AUTO" and at the same time
  487. specifying a @SequenceGenerator. In such a case, your custom
  488. sequence settings are used in the case where the preferred strategy
  489. of the underlying platform is SEQUENCE, such as for Oracle and
  490. PostgreSQL.
  491. Composite Keys
  492. ~~~~~~~~~~~~~~
  493. Doctrine 2 allows to use composite primary keys. There are however
  494. some restrictions opposed to using a single identifier. The use of
  495. the ``@GeneratedValue`` annotation is only supported for simple
  496. (not composite) primary keys, which means you can only use
  497. composite keys if you generate the primary key values yourself
  498. before calling ``EntityManager#persist()`` on the entity.
  499. To designate a composite primary key / identifier, simply put the
  500. @Id marker annotation on all fields that make up the primary key.
  501. Quoting Reserved Words
  502. ----------------------
  503. It may sometimes be necessary to quote a column or table name
  504. because it conflicts with a reserved word of the particular RDBMS
  505. in use. This is often referred to as "Identifier Quoting". To let
  506. Doctrine know that you would like a table or column name to be
  507. quoted in all SQL statements, enclose the table or column name in
  508. backticks. Here is an example:
  509. .. code-block:: php
  510. <?php
  511. /** @Column(name="`number`", type="integer") */
  512. private $number;
  513. Doctrine will then quote this column name in all SQL statements
  514. according to the used database platform.
  515. .. warning::
  516. Identifier Quoting is not supported for join column
  517. names or discriminator column names.
  518. .. warning::
  519. Identifier Quoting is a feature that is mainly intended
  520. to support legacy database schemas. The use of reserved words and
  521. identifier quoting is generally discouraged. Identifier quoting
  522. should not be used to enable the use non-standard-characters such
  523. as a dash in a hypothetical column ``test-name``. Also Schema-Tool
  524. will likely have troubles when quoting is used for case-sensitivity
  525. reasons (in Oracle for example).