1
0
mirror of synced 2024-12-13 22:56:04 +03:00

Brought most of the documentation up to date on 2.1

This commit is contained in:
Benjamin Eberlei 2011-07-13 20:31:01 +02:00
parent 660ead4b0e
commit 91b2c82c58
9 changed files with 213 additions and 57 deletions

View File

@ -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:

View File

@ -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
----

View File

@ -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
-----------

View File

@ -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
--------------------

View File

@ -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.

View File

@ -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

View File

@ -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>

View File

@ -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.

View File

@ -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