Brought most of the documentation up to date on 2.1
This commit is contained in:
parent
660ead4b0e
commit
91b2c82c58
@ -528,14 +528,16 @@ Optional attributes:
|
||||
- **inversedBy**: The inversedBy attribute designates the field in the
|
||||
entity that is the inverse side of the relationship.
|
||||
- **cascade**: Cascade Option
|
||||
- **fetch**: One of LAZY or EAGER
|
||||
- **fetch**: One of LAZY, EXTRA_LAZY or EAGER
|
||||
- **indexBy**: Index the collection by a field on the target entity.
|
||||
|
||||
**NOTE** For ManyToMany bidirectional relationships either side may
|
||||
.. note::
|
||||
|
||||
For ManyToMany bidirectional relationships either side may
|
||||
be the owning side (the side that defines the @JoinTable and/or
|
||||
does not make use of the mappedBy attribute, thus using a default
|
||||
join table).
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: php
|
||||
@ -635,6 +637,8 @@ Optional attributes:
|
||||
- **mappedBy**: This option specifies the property name on the
|
||||
targetEntity that is the owning side of this relation. Its a
|
||||
required attribute for the inverse side of a relationship.
|
||||
- **fetch**: One of LAZY, EXTRA_LAZY or EAGER.
|
||||
- **indexBy**: Index the collection by a field on the target entity.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -557,6 +557,9 @@ clauses:
|
||||
- TRIM([LEADING \| TRAILING \| BOTH] ['trchar' FROM] str) - Trim
|
||||
the string by the given trim char, defaults to whitespaces.
|
||||
- UPPER(str) - Return the upper-case of the given string.
|
||||
- DATE_ADD(date, days) - Add the number of days to a given date.
|
||||
- DATE_SUB(date, days) - Substract the number of days from a given date.
|
||||
- DATE_DIFF(date1, date2) - Calculate the difference in days between date1-date2.
|
||||
|
||||
Arithmetic operators
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
@ -1263,6 +1266,29 @@ number of results:
|
||||
entity might appear in many rows, effectively hydrating less than
|
||||
the specified number of results.
|
||||
|
||||
.. _dql-temporarily-change-fetch-mode:
|
||||
|
||||
Temporarily change fetch mode in DQL
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
While normally all your associations are marked as lazy or extra lazy you will have cases where you are using DQL and don't want to
|
||||
fetch join a second, third or fourth level of entities into your result, because of the increased cost of the SQL JOIN. You
|
||||
can mark a many-to-one or one-to-one association as fetched temporarily to batch fetch these entities using a WHERE .. IN query.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$query = $em->createQuery("SELECT u FROM MyProject\User u");
|
||||
$query->setFetchMode("MyProject\User", "address", "EAGER");
|
||||
$query->execute();
|
||||
|
||||
Given that there are 10 users and corresponding addresses in the database the executed queries will look something like:
|
||||
|
||||
.. code-block:: sql
|
||||
|
||||
SELECT * FROM users;
|
||||
SELECT * FROM address WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
|
||||
|
||||
|
||||
EBNF
|
||||
----
|
||||
|
@ -7,6 +7,17 @@ Frequently Asked Questions
|
||||
what is often asked. If you stumble accross an unanswerd question please write a mail to the mailing-list or
|
||||
join the #doctrine channel on Freenode IRC.
|
||||
|
||||
Database Schema
|
||||
---------------
|
||||
|
||||
How do I set the charset and collation for MySQL tables?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can't set these values inside the annotations, yml or xml mapping files. To make a database
|
||||
work with the default charset and collation you should configure MySQL to use it as default charset,
|
||||
or create the database with charset and collation details. This way they get inherited to all newly
|
||||
created database tables and columns.
|
||||
|
||||
Entity Classes
|
||||
--------------
|
||||
|
||||
@ -23,7 +34,7 @@ Doctrine does not support to set the default values in columns through the "DEFA
|
||||
This is not necessary however, you can just use your class properties as default values. These are then used
|
||||
upon insert:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: php
|
||||
|
||||
class User
|
||||
{
|
||||
@ -47,7 +58,7 @@ or adding entities to a collection twice. You have to check for both conditions
|
||||
in the code before calling ``$em->flush()`` if you know that unique constraint failures
|
||||
can occur.
|
||||
|
||||
In `Symfony 2<http://www.symfony.com>`_ for example there is a Unique Entity Validator
|
||||
In `Symfony 2 <http://www.symfony.com>`_ for example there is a Unique Entity Validator
|
||||
to achieve this task.
|
||||
|
||||
For collections you can check with ``$collection->contains($entity)`` if an entity is already
|
||||
@ -128,7 +139,7 @@ Can I use Inheritance with Doctrine 2?
|
||||
|
||||
Yes, you can use Single- or Joined-Table Inheritance in Doctrine 2.
|
||||
|
||||
See the documentation chapter on :doc:`inheritance mapping <inheritance-mapping>`_ for
|
||||
See the documentation chapter on :doc:`inheritance mapping <inheritance-mapping>` for
|
||||
the details.
|
||||
|
||||
Why does Doctrine not create proxy objects for my inheritance hierachy?
|
||||
@ -144,12 +155,16 @@ EntityGenerator
|
||||
Why does the EntityGenerator not do X?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.
|
||||
The EntityGenerator is not a full fledged code-generator that solves all tasks. Code-Generation
|
||||
is not a first-class priority in Doctrine 2 anymore (compared to Doctrine 1). The EntityGenerator
|
||||
is supposed to kick-start you, but not towards 100%.
|
||||
|
||||
Why does the EntityGenerator not generate inheritance correctly?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.
|
||||
Just from the details of the discriminator map the EntityGenerator cannot guess the inheritance hierachy.
|
||||
This is why the generation of inherited entities does not fully work. You have to adjust some additional
|
||||
code to get this one working correctly.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
@ -42,6 +42,19 @@ for updates, which means when you call flush on the EntityManager these entities
|
||||
even if properties changed. Read-Only allows to persist new entities of a kind and remove existing
|
||||
ones, they are just not considered for updates.
|
||||
|
||||
Extra-Lazy Collections
|
||||
----------------------
|
||||
|
||||
If entities hold references to large collections you will get performance and memory problems initializing them.
|
||||
To solve this issue you can use the EXTRA_LAZY fetch-mode feature for collections. See the :doc:`tutorial <../tutorials/extra-lazy-associations>`
|
||||
for more information on how this fetch mode works.
|
||||
|
||||
Temporarily change fetch mode in DQL
|
||||
------------------------------------
|
||||
|
||||
See :ref:`Doctrine Query Language chapter <dql-temporarily-change-fetch-mode>`
|
||||
|
||||
|
||||
Apply Best Practices
|
||||
--------------------
|
||||
|
||||
|
@ -229,7 +229,6 @@ which meta-column is the discriminator column of this tree.
|
||||
* @param string $alias The alias of the entity result or joined entity result the discriminator
|
||||
* column should be used for.
|
||||
* @param string $discrColumn The name of the discriminator column in the SQL result set.
|
||||
* @todo Rename: addDiscriminatorColumn
|
||||
*/
|
||||
public function setDiscriminatorColumn($alias, $discrColumn)
|
||||
|
||||
@ -363,4 +362,28 @@ are actually a subtype of User. When using DQL, Doctrine
|
||||
automatically includes the necessary joins for this mapping
|
||||
strategy but with native SQL it is your responsibility.
|
||||
|
||||
ResultSetMappingBuilder
|
||||
-----------------------
|
||||
|
||||
There are some downsides with Native SQL queries. The primary one is that you have to adjust all result set mapping
|
||||
definitions if names of columns change. In DQL this is detected dynamically when the Query is regenerated with
|
||||
the current metadata.
|
||||
|
||||
To avoid this hassle you can use the ``ResultSetMappingBuilder`` class. It allows to add all columns of an entity
|
||||
to a result set mapping. To avoid clashes you can optionally rename specific columns when you are doing the same
|
||||
in your sQL statement:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
$sql = "SELECT u.id, u.name, a.id AS address_id, a.street, a.city " .
|
||||
"FROM users u INNER JOIN address a ON u.address_id = a.id";
|
||||
|
||||
$rsm = new ResultSetMappingBuilder;
|
||||
$rsm->addRootEntityFromClassMetadata('MyProject\User', 'u');
|
||||
$rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', array('id' => 'address_id'));
|
||||
|
||||
For entites with more columns the builder is very convenient to use. It extends the ``ResultSetMapping`` class
|
||||
and as such has all the functionality of it as well. Currently the ``ResultSetMappingBuilder`` does not support
|
||||
entities with inheritance.
|
||||
|
@ -692,10 +692,28 @@ methods on a repository as follows:
|
||||
|
||||
You can also load by owning side associations through the repository:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$number = $em->find('MyProject\Domain\Phonenumber', 1234);
|
||||
$user = $em->getRepository('MyProject\Domain\User')->findOneBy(array('phone' => $number->getId()));
|
||||
|
||||
Take not that this only works by passing the ID of the associated entity, not yet by passing the associated entity itself.
|
||||
Be careful that this only works by passing the ID of the associated entity, not yet by passing the associated entity itself.
|
||||
|
||||
The ``EntityRepository#findBy()`` method additionally accepts orderings, limit and offset as second to fourth parameters:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$tenUsers = $em->getRepository('MyProject\Domain\User')-findBy(array('age' => 20), array('name' => 'ASC'), 10, 0);
|
||||
|
||||
If you pass an array of values Doctrine will convert the query into a WHERE field IN (..) query automatically:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
$users = $em->getRepository('MyProject\Domain\User')-findBy(array('age' => array(20, 30, 40)));
|
||||
// translates roughly to: SELECT * FROM users WHERE age IN (20, 30, 40)
|
||||
|
||||
An EntityRepository also provides a mechanism for more concise
|
||||
calls through its use of ``__call``. Thus, the following two
|
||||
|
@ -448,7 +448,7 @@ Optional attributes for owning One-to-One:
|
||||
field on the inverse entity that contains the back-reference.
|
||||
- orphan-removal - If true, the inverse side entity is always
|
||||
deleted when the owning side entity is. Defaults to false.
|
||||
- fetch - Either LAZY or FETCH, defaults to LAZY. This attribute
|
||||
- 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.
|
||||
|
||||
@ -501,7 +501,7 @@ Optional attributes:
|
||||
always deleted when the owning side entity is and it is not
|
||||
connected to any other owning side entity anymore. Defaults to
|
||||
false.
|
||||
- fetch - Either LAZY or FETCH, defaults to LAZY.
|
||||
- fetch - Either LAZY or EAGER, defaults to LAZY.
|
||||
|
||||
This definition relies on a bunch of mapping defaults with regards
|
||||
to the naming of the join-column/foreign key. The explicitly
|
||||
@ -547,7 +547,8 @@ Required attributes:
|
||||
Optional attributes:
|
||||
|
||||
|
||||
- fetch - Either LAZY or FETCH, defaults to LAZY.
|
||||
- fetch - Either LAZY, EXTRA_LAZY or EAGER, defaults to LAZY.
|
||||
- index-by: Index the collection by a field on the target entity.
|
||||
|
||||
Defining Many-To-Many Associations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -579,7 +580,8 @@ 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.
|
||||
- fetch - Either LAZY or FETCH, defaults to LAZY.
|
||||
- fetch - Either LAZY, EXTRA_LAZY or EAGER, defaults to LAZY.
|
||||
- index-by: Index the collection by a field on the target entity.
|
||||
|
||||
The mapping defaults would lead to a join-table with the name
|
||||
"User\_Group" being created that contains two columns "user\_id"
|
||||
@ -698,4 +700,26 @@ table you can use the ``<indexes />`` and
|
||||
You have to specify the column and not the entity-class field names
|
||||
in the index and unique-constraint definitions.
|
||||
|
||||
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.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://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>
|
||||
|
@ -144,55 +144,92 @@ Use-Case 1: Dynamic Attributes
|
||||
|
||||
We keep up the example of an Article with arbitrary attributes, the mapping looks like this:
|
||||
|
||||
.. code-block:: php
|
||||
.. configuration-block::
|
||||
|
||||
<?php
|
||||
namespace Application\Model;
|
||||
.. code-block:: php
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
<?php
|
||||
namespace Application\Model;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class Article
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
/** @Column(type="string") */
|
||||
private $title;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="ArticleAttribute", mappedBy="article", cascade={"ALL"}, indexBy="attribute")
|
||||
* @Entity
|
||||
*/
|
||||
private $attributes;
|
||||
|
||||
public function addAttribute($name, $value)
|
||||
class Article
|
||||
{
|
||||
$this->attributes[$name] = new ArticleAttribute($name, $value, $this);
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
/** @Column(type="string") */
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="ArticleAttribute", mappedBy="article", cascade={"ALL"}, indexBy="attribute")
|
||||
*/
|
||||
private $attributes;
|
||||
|
||||
public function addAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = new ArticleAttribute($name, $value, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class ArticleAttribute
|
||||
{
|
||||
/** @Id @ManyToOne(targetEntity="Article", inversedBy="attributes") */
|
||||
private $article;
|
||||
|
||||
/** @Id @Column(type="string") */
|
||||
private $attribute;
|
||||
|
||||
/** @Column(type="string") */
|
||||
private $value;
|
||||
|
||||
public function __construct($name, $value, $article)
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class ArticleAttribute
|
||||
{
|
||||
$this->attribute = $name;
|
||||
$this->value = $value;
|
||||
$this->article = $article;
|
||||
/** @Id @ManyToOne(targetEntity="Article", inversedBy="attributes") */
|
||||
private $article;
|
||||
|
||||
/** @Id @Column(type="string") */
|
||||
private $attribute;
|
||||
|
||||
/** @Column(type="string") */
|
||||
private $value;
|
||||
|
||||
public function __construct($name, $value, $article)
|
||||
{
|
||||
$this->attribute = $name;
|
||||
$this->value = $value;
|
||||
$this->article = $article;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://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>
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Application\Model\ArticleAttribute:
|
||||
type: entity
|
||||
id:
|
||||
article:
|
||||
associationKey: true
|
||||
attribute:
|
||||
type: string
|
||||
fields:
|
||||
value:
|
||||
type: string
|
||||
manyToOne:
|
||||
article:
|
||||
targetEntity: Article
|
||||
inversedBy: attributes
|
||||
|
||||
|
||||
Use-Case 2: Simple Derived Identity
|
||||
@ -311,4 +348,4 @@ a simple surrogate key. This performance impact is mostly due to additional PHP
|
||||
necessary to handle this kind of keys, most notably when using derived identifiers.
|
||||
|
||||
On the SQL side there is not much overhead as no additional or unexpected queries have to be
|
||||
executed to manage entities with derived foreign keys.
|
||||
executed to manage entities with derived foreign keys.
|
||||
|
@ -1,10 +1,6 @@
|
||||
Extra Lazy Associations
|
||||
=======================
|
||||
|
||||
.. note::
|
||||
|
||||
This feature is scheduled for version 2.1 of Doctrine and not included in the 2.0.x series.
|
||||
|
||||
In many cases associations between entities can get pretty large. Even in a simple scenario like a blog.
|
||||
where posts can be commented, you always have to assume that a post draws hundrets of comments.
|
||||
In Doctrine 2.0 if you accessed an association it would always get loaded completly into memory. This
|
||||
|
Loading…
Reference in New Issue
Block a user