11/02/2018 - DOCTRINE, SYMFONY
I've been using Symfony and Doctrine for a few good years now and don't even remember using built in Doctrine methods like find
, findAll
, findBy
and findOneBy
. Instead I always created my own methods in repository class that used EntityRepository
. In this example we choose composition over inheritance and adopting Dependency Inversion Principle.
We won't use this because it inherits everything you don't need! Just showing how it is done.
namespace CustomerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="customer")
* @ORM\Entity(repositoryClass="CustomerBundle\Repository\CustomerRepository")
*/
class Customer
{
...
}
namespace CustomerBundle\Repository;
use Doctrine\ORM\EntityRepository;
class CustomerRepository extends EntityRepository
{
public function findAll()
{
return $this->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}
public function findOneById($id)
{
return $this->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}
services:
customer.repository.customer:
class: CustomerBundle\Repository\CustomerRepository
factory: [ "@doctrine.orm.entity_manager", getRepository ]
arguments:
- CustomerBundle\Entity\Customer
namespace CustomerBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="customer")
*/
class Customer
{
...
}
Use this version over the V2.
namespace CustomerBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
abstract class AbstractRepository
{
private $entityManager;
private $entityName;
public function __construct(EntityManagerInterface $entityManager, string $entityName)
{
$this->entityManager = $entityManager;
$this->entityName = $entityName;
}
protected function getEntityManager(): EntityManagerInterface
{
return $this->entityManager;
}
protected function getRepository(): EntityRepository
{
return $this->entityManager->getRepository($this->entityName);
}
}
namespace CustomerBundle\Repository;
use Doctrine\ORM\EntityManagerInterface;
class CustomerRepository extends AbstractRepository
{
public function __construct(EntityManagerInterface $entityManager)
{
parent::__construct($entityManager, Customer::class);
}
public function findAll()
{
return $this->getRepository()->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}
public function findOneById($id)
{
return $this->getRepository()->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}
CustomerBundle\Repository\CustomerRepository: ~
CustomerBundle\Repository\CustomerRepositoryInterface: '@CustomerBundle\Repository\CustomerRepository'
namespace CustomerBundle\Repository;
interface CustomerRepositoryInterface
{
public function findAll();
public function findOneById($id);
}
namespace CustomerBundle\Repository;
use Doctrine\ORM\EntityRepository;
class CustomerRepository implements CustomerRepositoryInterface
{
private $entityRepository;
public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}
public function findAll()
{
return $this->entityRepository->createQueryBuilder('c')
->getQuery()
->getArrayResult();
}
public function findOneById($id)
{
return $this->entityRepository->createQueryBuilder('c')
->where('c.id = :id')
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}
services:
customer.doctrine.entity_repository:
class: Doctrine\ORM\EntityRepository
factory: [ "@doctrine.orm.entity_manager", getRepository ]
arguments:
- CustomerBundle\Entity\Customer
customer.repository.customer:
class: CustomerBundle\Repository\CustomerRepository
arguments:
- "@customer.doctrine.entity_repository"