Basic Mapping ============= This guide explains the basic mapping of entities and properties. After working through this guide you should know: - How to create PHP classes that can be saved in the database with Doctrine - How to configure the mapping between columns on tables and properties on entities. - Defining primary keys and how identifiers are generated by Doctrine - What Doctrine types are Mapping of associations will be covered in the next chapter on :doc:`Association Mapping `. Guide Assumptions ----------------- You should have already :doc:`installed and configure ` Doctrine. Creating Classes for the Database --------------------------------- Every PHP Class that you want to save in the database using Doctrine need to be marked as "Entity". The term "Entity" describes objects that have identity over many independent requests. This identity is usually achieved by assigning a unique identifier to an entity. In this tutorial the following ``Message`` PHP class will serve as example Entity: .. code-block:: php ` - :doc:`XML ` - :doc:`YAML ` - PHP code This manual usually mentions docblock annotations in all the examples that are spread throughout all chapters, however for many examples alternative YAML and XML examples are given as well. .. note:: All metadata drivers perform equally. Once the metadata of a class has been read from the source (annotations, xml or yaml) it is stored in an instance of the ``Doctrine\ORM\Mapping\ClassMetadata`` class and these instances are stored in the metadata cache. If you're not using a metadata cache (not recommended!) then the XML driver is the fastest by using PHP's native XML support. Marking our ``Message`` entity for Doctrine is straightforward: .. configuration-block:: .. code-block:: php .. code-block:: yaml Message: type: entity # ... With no additional information given Doctrine expects the entity to be saved into a table with the same name as the class in our case ``Message``. You can change this by configuring information about the table: .. configuration-block:: .. code-block:: php .. code-block:: yaml Message: type: entity table: message # ... Now the class ``Message`` will be saved and fetched from the table ``message``. Property Mapping ---------------- The next step after defining a PHP class as entity is mapping of properties to columns in a table. To configure a property use the ``@Column`` docblock annotation. The ``type`` attribute specifies the Doctrine Mapping Type to use for the field. If the type is not specified, ``string`` is used as the default mapping type. .. configuration-block:: .. code-block:: php .. code-block:: yaml Message: type: entity fields: id: type: integer text: length: 140 postedAt: type: datetime name: posted_at Because we don't explicitly specify a column name, Doctrine assumes the field name is also the column name. In the example we configured the property ``id`` to map to the column ``id`` using the mapping type ``integer``. The field ``text`` is mapped to the column ``text`` with the default mapping type ``string`` and ``postedAt`` is of the datetime type, but mapped to a column called ``posted_at``. The Column annotation has some more attributes. Here is a complete list: - ``type``: (optional, defaults to 'string') The mapping type to use for the column. - ``name``: (optional, defaults to field name) The name of the column in the database. - ``length``: (optional, default 255) The length of the column in the database. (Applies only if a string-valued column is used). - ``unique``: (optional, default FALSE) Whether the column is a unique key. - ``nullable``: (optional, default FALSE) Whether the database column is nullable. - ``precision``: (optional, default 0) The precision for a decimal (exact numeric) column. (Applies only if a decimal column is used.) - ``scale``: (optional, default 0) The scale for a decimal (exact numeric) column. (Applies only if a decimal column is used.) - ``columnDefinition``: (optional) Allows to define a custom DDL snippet that is used to create the column. Warning: This normally confuses the SchemaTool to always detect the column as changed. - ``options``: (optional) Key-value pairs of options that get passed to the underlying database platform when generating DDL statements. Doctrine Mapping Types ---------------------- A Doctrine Mapping Type defines the conversion the type of a PHP variable and an SQL type. All Mapping Types that ship with Doctrine are fully portable between the supported database systems. You can add your own custom mapping types to add more conversions. As an example the Doctrine Mapping Type ``string`` defines the mapping from a PHP string to a SQL VARCHAR (or VARCHAR2 etc. depending on the RDBMS brand). Here is a quick overview of the built-in mapping types: - ``string``: Type that maps a SQL VARCHAR to a PHP string. - ``integer``: Type that maps a SQL INT to a PHP integer. - ``smallint``: Type that maps a database SMALLINT to a PHP integer. - ``bigint``: Type that maps a database BIGINT to a PHP string. - ``boolean``: Type that maps a SQL boolean to a PHP boolean. - ``decimal``: Type that maps a SQL DECIMAL to a PHP string. - ``date``: Type that maps a SQL DATETIME to a PHP DateTime object. - ``time``: Type that maps a SQL TIME to a PHP DateTime object. - ``datetime``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP DateTime object. - ``datetimetz``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP DateTime object with timezone. - ``text``: Type that maps a SQL CLOB to a PHP string. - ``object``: Type that maps a SQL CLOB to a PHP object using ``serialize()`` and ``unserialize()`` - ``array``: Type that maps a SQL CLOB to a PHP array using ``serialize()`` and ``unserialize()`` - ``simple_array``: Type that maps a SQL CLOB to a PHP array using ``implode()`` and ``explode()``, with a comma as delimiter. *IMPORTANT* Only use this type if you are sure that your values cannot contain a ",". - ``json_array``: Type that maps a SQL CLOB to a PHP array using ``json_encode()`` and ``json_decode()`` - ``float``: Type that maps a SQL Float (Double Precision) to a PHP double. *IMPORTANT*: Works only with locale settings that use decimal points as separator. - ``guid``: Type that maps a database GUID/UUID to a PHP string. Defaults to varchar but uses a specific type if the platform supports it. - ``blob``: Type that maps a SQL BLOB to a PHP resource stream .. note:: DateTime and Object types are compared by reference, not by value. Doctrine updates this values if the reference changes and therefore behaves as if these objects are immutable value objects. .. warning:: All Date types assume that you are exclusively using the default timezone set by `date_default_timezone_set() `_ or by the php.ini configuration ``date.timezone``. Working with different timezones will cause troubles and unexpected behavior. If you need specific timezone handling you have to handle this in your domain, converting all the values back and forth from UTC. There is also a :doc:`cookbook entry <../cookbook/working-with-datetime>` on working with datetimes that gives hints for implementing multi timezone applications. Identifiers / Primary Keys -------------------------- Every entity class needs an identifier/primary key. You designate the field that serves as the identifier with the ``@Id`` annotation: .. configuration-block:: .. code-block:: php .. code-block:: yaml MyPersistentClass: type: entity id: id: type: integer fields: name: length: 50 This definition is missing an ID generation strategy, which means that your code needs to assign the identifier manually before passing a new entity to ``EntityManager#persist($entity)``. Doctrine can alternatively generate identifiers for entities using generation strategies, using database sequences or auto incrementing numbers. .. configuration-block:: .. code-block:: php .. code-block:: yaml MyPersistentClass: type: entity id: id: type: integer generator: strategy: AUTO fields: name: length: 50 This tells Doctrine to automatically generate a value for the identifier. How this value is generated is specified by the ``strategy`` attribute, which is optional and defaults to 'AUTO'. A value of ``AUTO`` tells Doctrine to use the generation strategy that is preferred by the currently used database platform. See below for details. Identifier Generation Strategies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The previous example showed how to use the default identifier generation strategy without knowing the underlying database with the AUTO-detection strategy. It is also possible to specify the identifier generation strategy more explicitly, which allows to make use of some additional features. Here is the list of possible generation strategies: - ``AUTO`` (default): Tells Doctrine to pick the strategy that is preferred by the used database platform. The preferred strategies are IDENTITY for MySQL, SQLite and MsSQL and SEQUENCE for Oracle and PostgreSQL. This strategy provides full portability. - ``SEQUENCE``: Tells Doctrine to use a database sequence for ID generation. This strategy does currently not provide full portability. Sequences are supported by Oracle and PostgreSql. - ``IDENTITY``: Tells Doctrine to use special identity columns in the database that generate a value on insertion of a row. This strategy does currently not provide full portability and is supported by the following platforms: MySQL/SQLite (AUTO\_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL). - ``TABLE``: Tells Doctrine to use a separate table for ID generation. This strategy provides full portability. ***This strategy is not yet implemented!*** - ``NONE``: Tells Doctrine that the identifiers are assigned (and thus generated) by your code. The assignment must take place before a new entity is passed to ``EntityManager#persist``. NONE is the same as leaving off the @GeneratedValue entirely. Sequence Generator ^^^^^^^^^^^^^^^^^^ The Sequence Generator can currently be used in conjunction with Oracle or Postgres and allows some additional configuration options besides specifying the sequence's name: .. configuration-block:: .. code-block:: php .. code-block:: yaml MyPersistentClass: type: entity id: id: type: integer generator: strategy: SEQUENCE sequenceGenerator: sequenceName: tablename_seq allocationSize: 100 initialValue: 1 The initial value specifies at which value the sequence should start. The allocationSize is a powerful feature to optimize INSERT performance of Doctrine. The allocationSize specifies by how much values the sequence is incremented whenever the next value is retrieved. If this is larger than 1 (one) Doctrine can generate identifier values for the allocationSizes amount of entities. In the above example with ``allocationSize=100`` Doctrine 2 would only need to access the sequence once to generate the identifiers for 100 new entities. *The default allocationSize for a @SequenceGenerator is currently 10.* .. caution:: The allocationSize is detected by SchemaTool and transformed into an "INCREMENT BY " clause in the CREATE SEQUENCE statement. For a database schema created manually (and not SchemaTool) you have to make sure that the allocationSize configuration option is never larger than the actual sequences INCREMENT BY value, otherwise you may get duplicate keys. .. note:: It is possible to use strategy="AUTO" and at the same time specifying a @SequenceGenerator. In such a case, your custom sequence settings are used in the case where the preferred strategy of the underlying platform is SEQUENCE, such as for Oracle and PostgreSQL. Composite Keys ~~~~~~~~~~~~~~ Doctrine 2 allows to use composite primary keys. There are however some restrictions opposed to using a single identifier. The use of the ``@GeneratedValue`` annotation is only supported for simple (not composite) primary keys, which means you can only use composite keys if you generate the primary key values yourself before calling ``EntityManager#persist()`` on the entity. To designate a composite primary key / identifier, simply put the @Id marker annotation on all fields that make up the primary key. Quoting Reserved Words ---------------------- Sometimes it is necessary to quote a column or table name because of reserved word conflicts. Doctrine does not quote identifiers automatically, because it leads to more problems then it would solve. Quoting tables and column names needs to be done explicitly using ticks in the definition. .. code-block:: php setQuoteStrategy(new AnsiQuoteStrategy()); Custom Mapping Types -------------------- Doctrine allows you to create new mapping types. This can come in handy when you're missing a specific mapping type or when you want to replace the existing implementation of a mapping type. In order to create a new mapping type you need to subclass ``Doctrine\DBAL\Types\Type`` and implement/override the methods as you wish. Here is an example skeleton of such a custom type class: .. code-block:: php getConnection(); $conn->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype'); When registering the custom types in the configuration you specify a unique name for the mapping type and map that to the corresponding fully qualified class name. Now the new type can be used when mapping columns: .. code-block:: php