Skip to content

Commit 8141924

Browse files
committed
Merge branch 'doctrine-repositories' of git://github.com/thaberkern/symfony-docs into thaberkern-doctrine-repositories
2 parents 51df9fe + 2aabfaf commit 8141924

File tree

1 file changed

+168
-6
lines changed

1 file changed

+168
-6
lines changed

book/doctrine/orm.rst

Lines changed: 168 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ any PHP class:
4747

4848
.. code-block:: php
4949
50-
// Acme/HelloBundle/Entity/User.php
50+
// src/Acme/HelloBundle/Entity/User.php
5151
namespace Acme\HelloBundle\Entity;
5252
5353
class User
@@ -85,7 +85,7 @@ write mapping information with annotations, XML, or YAML:
8585

8686
.. code-block:: php-annotations
8787
88-
// Acme/HelloBundle/Entity/User.php
88+
// src/Acme/HelloBundle/Entity/User.php
8989
namespace Acme\HelloBundle\Entity;
9090
9191
/**
@@ -108,7 +108,7 @@ write mapping information with annotations, XML, or YAML:
108108
109109
.. code-block:: yaml
110110
111-
# Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
111+
# src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
112112
Acme\HelloBundle\Entity\User:
113113
type: entity
114114
table: user
@@ -124,7 +124,7 @@ write mapping information with annotations, XML, or YAML:
124124
125125
.. code-block:: xml
126126
127-
<!-- Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
127+
<!-- src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
128128
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
129129
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
130130
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
@@ -167,7 +167,7 @@ Eventually, use your entity and manage its persistent state with Doctrine:
167167

168168
.. code-block:: php
169169
170-
// Acme/HelloBundle/Controller/UserController.php
170+
// src/Acme/HelloBundle/Controller/UserController.php
171171
namespace Acme\HelloBundle\Controller;
172172
173173
use Acme\HelloBundle\Entity\User;
@@ -215,6 +215,7 @@ losing your existing data. So first let's just add a new property to our
215215

216216
.. code-block:: php
217217
218+
// src/Acme/HelloBundle/Entity/User.php
218219
namespace Acme\HelloBundle\Entity;
219220
220221
/** @orm:Entity */
@@ -234,6 +235,166 @@ you just need to run the following command:
234235
Now your database will be updated and the new column added to the database
235236
table.
236237

238+
.. index::
239+
single: Doctrine ORM; Queries;
240+
241+
Queries
242+
~~~~~~~
243+
244+
As you have already seen, working with single objects is straight forward and
245+
easy with the entity manager. But how to query a set of objects? As every
246+
operation this is done via the entity manager. So let us change the delete
247+
action from the previous example to use a query instead of loading the object
248+
and afterwards delete it.
249+
250+
.. code-block:: php
251+
252+
public function deleteAction($id)
253+
{
254+
$query = $this->get('doctrine')->getEntityManager()
255+
->createQuery('DELETE FROM Acme\HelloBundle\Entity\User u
256+
WHERE u.id = :id');
257+
$query->setParameters(array(
258+
'id' => $id
259+
));
260+
261+
$query->execute();
262+
263+
// ...
264+
}
265+
266+
Of course you can use SELECT and UPDATE queries too. Doctrine brings it own
267+
Query Language called DQL (Doctrine Query Language). The DQL has some
268+
similarities with SQL but is a query language with its own syntax.
269+
270+
.. tip::
271+
272+
You can read more about the Doctrine Query Language on the
273+
official `Doctrine Query Language documentation`_ website.
274+
275+
.. index::
276+
single: Doctrine ORM; Repository;
277+
278+
Repositories
279+
~~~~~~~~~~~~
280+
281+
It is bad practice to make queries in the Symfony controllers. Such queries
282+
should be done in the model layer of your bundle. Doctrine is using special
283+
classes called Repositories to encapsulate queries.
284+
285+
Doctrine provides a default implementation for your repository classes, so you
286+
can use their common methods to query your entities data. One of them is the
287+
``findAll`` function.
288+
289+
.. code-block:: php
290+
291+
$em = $this->get('doctrine')->getEntityManager();
292+
$users = $em->getRepository('AcmeHelloBundle:User')
293+
->findAll();
294+
295+
If you want to create your own function to query or manipulate your data, you
296+
need to create a custom repository class for an entity. To do so you need to
297+
add the name of the repository class to your mapping definition.
298+
299+
.. configuration-block::
300+
301+
.. code-block:: php-annotations
302+
303+
// src/Acme/HelloBundle/Entity/User.php
304+
namespace Acme\HelloBundle\Entity;
305+
306+
/**
307+
* @orm:Entity(repositoryClass="Acme\HelloBundle\Repository\UserRepository")
308+
*/
309+
class User
310+
{
311+
//...
312+
}
313+
314+
.. code-block:: yaml
315+
316+
# src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.yml
317+
Acme\HelloBundle\Entity\User:
318+
type: entity
319+
table: user
320+
repositoryClass: Acme\HelloBundle\Repository\UserRepository
321+
#...
322+
323+
.. code-block:: xml
324+
325+
<!-- src/Acme/HelloBundle/Resources/config/doctrine/Acme.HelloBundle.Entity.User.orm.xml -->
326+
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
327+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
328+
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
329+
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
330+
331+
<entity name="Acme\HelloBundle\Entity\User" table="user"
332+
repository-class="Acme\HelloBundle\Repository\UserRepository">
333+
<id name="id" type="integer" column="id">
334+
<generator strategy="AUTO"/>
335+
</id>
336+
<field name="name" column="name" type="string" length="255" />
337+
</entity>
338+
339+
</doctrine-mapping>
340+
341+
The repository class is created if you run the following command to create your
342+
entities.
343+
344+
$ php app/console doctrine:generate:entities
345+
346+
If you have already generated your entity class before adding the repositoryClass
347+
mapping you have to create the class on your own. For that create the class in
348+
the Repository folder of your bundle. The class has to extend
349+
``Doctrine\ORM\EntityRepository``.
350+
After the creation of the class you can add any method to query your entities.
351+
The following code shows a sample repository class.
352+
353+
.. code-block:: php
354+
355+
// src/Acme/HelloBundle/Repository/UserRepository.php
356+
namespace Acme\HelloBundle\Repository;
357+
358+
use Doctrine\ORM\EntityRepository;
359+
360+
class UserRepository extends EntityRepository
361+
{
362+
public function findAllOrderedByName()
363+
{
364+
return $this->getEntityManager()
365+
->createQuery('SELECT u FROM Acme\HelloBundle\Entity\User u
366+
ORDER BY u.name ASC')
367+
->getResult();
368+
}
369+
}
370+
371+
.. tip::
372+
373+
The entity manager can be accessed via ``$this->getEntityManager()`` in the
374+
repositories functions.
375+
376+
.. note::
377+
378+
Note that there is a drawback when using a DQL DELETE statement: it does not
379+
remove the entity from the UnitOfWork if it was previously loaded
380+
(same issue for UPDATE statements).
381+
The UnitOfWork works in the memory (and then flushes the changes) whereas
382+
your DQL query will act on the database. So the UnitOfWork and the database
383+
are not in sync anymore.
384+
This can be an issue for instance if your query makes a change in your User
385+
entity affecting the one loaded in memory by your UserProvider for the
386+
authentication as the User object will be out of sync.
387+
388+
The usage of this new method in your repository class is the same as with the
389+
default finder functions.
390+
391+
.. code-block:: php
392+
393+
$em = $this->get('doctrine')->getEntityManager();
394+
$users = $em->getRepository('AcmeHelloBundle:User')
395+
->findAllOrderedByName();
396+
397+
237398
.. index::
238399
single: Configuration; Doctrine ORM
239400
single: Doctrine; ORM Configuration
@@ -242,7 +403,7 @@ Configuration
242403
-------------
243404

244405
In the overview we already described the only necessary configuration option
245-
to get the Doctrine ORM running with Symfony 2. All the other configuration
406+
to get the Doctrine ORM running with Symfony2. All the other configuration
246407
options are used with reasonable default values.
247408

248409
This following configuration example shows all the configuration defaults that
@@ -617,3 +778,4 @@ get the choices. If not set all entities will be used.
617778

618779
.. _documentation: http://www.doctrine-project.org/docs/orm/2.0/en
619780
.. _Doctrine: http://www.doctrine-project.org
781+
.. _Doctrine Query Language documentation: http://www.doctrine-project.org/docs/orm/2.0/en/reference/dql-doctrine-query-language.html

0 commit comments

Comments
 (0)