Symfony2 Repository

Szervezzük a lekérdezéseinket repository-kba, hogy szebb, átláthatóbb, könnyebben kezelhető kódot kapjunk és rövidebbek legyenek a controllerjeink. A symfony2-es leírásokban szerintem nincsen eléggé hangsúlyozva ez a dolog, pedig könnyebben emészthető kódot lehet így írni.

Létezik pár különböző előre definiált repository, pl ha az összes rekordot visszaszeretnénk kapni vagy csak bizonyos feltételek mentén szeretnénk visszakapni 1-1 rekordot:
 
# pl az összes autó rekordot meg szeretnénk kapni
$entities = $em->getRepository('WebBlogBundle:Car')->findAll();
# ha csak egy autót szeretnénk megkapni az azonosítója alapján
$entity = $em->getRepository('WebBlogBundle:Car')->find($id)
# ha egy autót szeretnénk a rendszáma alapján visszakapni
$entity = $em->getRepository('WebUserBundle:Car')->findby(array('rendszam'=>$rendszam));

Ez szép és jó, de mi van ha mi egy szebb összetettebb lekérdezést szeretnénk írni különböző feltételekkel. Akkor az oldalon a régebbi példákban ilyen kódot írtunk volna a controllerünkbe:
 
# itt most az aktív és inaktív státuszú rekordoknak az "id" mezőjét fogjuk visszakapni időrendszerint rendezve.
$entities = $em->getRepository('WebBlogBundle:Car'); 
$query = $entities->createQueryBuilder('n')
	->select('n.id')
	->where('n.status = :status_active')
	->setParameter('status_active','active')
	->orwhere('n.status = :status_inactive')
	->setParameter('status_inactive',"inactive")
	->orderBy('n.date','DESC')
	->getQuery();
$entities = $query->getResult();

Ehelyett csak ennyit fogunk írni a controllerbe:
 
$entities = $em->getRepository('WebBlogBundle:Car')->getCarList();

Csináhatunk az entity mappába egy CarRepository.php fájlt a következő tartalommal:
 
<?php
// src/Web/BlogBundle/Entity/CarRepository.php
namespace Web\BlogBundle\Entity;

use Doctrine\ORM\EntityRepository;

class CarRepository extends EntityRepository
{
	/*
	*
	* SQL: SELECT id FROM car WHERE status = 'active' OR status = 'inactive' ORDER BY date DESC
	*
	*/
    public function getCarList()
    {
		$entities = $this->createQueryBuilder('n')
				->select('count(n.id)')
				->where('n.status = :status_active')
				->setParameter('status_active','active')
				->orwhere('n.status = :status_inactive')
				->setParameter('status_inactive',"inactive")
				->orderBy('n.date','DESC')
			->getQuery()->getResult();
		
		return $entities;
    } 
}

Ezután még ne feledkezzünk el arról, hogy aki az entity-ket xml-el kezeli, azok a Resources\config\doctrine\Car.orm.xml fájlban így módosítsanak:
 
ezt:
<entity name="Web\BlogBundle\Entity\Car" table="car">
erre:
<entity name="Web\BlogBundle\Entity\Car" table="car" repository-class="Web\BlogBundle\Entity\CarRepository">

Aki annotációkat használ az az Entity mappában a Car.php entity fájljába szúrja be ezt:
 
// src/Web\BlogBundle/Entity/Car.php
namespace Web\BlogBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Web\BlogBundle\Entity\CarRepository")
 */
class Car
{
    //...
}

http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes
2015.08.03.