@@ -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:
234235Now your database will be updated and the new column added to the database
235236table.
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
244405In 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
246407options are used with reasonable default values.
247408
248409This 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