Doctrine自定义存储库链接过滤器?

时间:2017-06-07 15:34:21

标签: php doctrine-orm query-builder

为了创建一个基于多个条件返回实体的组合查询,链接自定义存储库方法的正确方法是什么。

这是我做的:

use Doctrine\ORM\EntityRepository;

class ingredientRepository extends EntityRepository
{

    private $query;

    public function initNewQuery()
    {
       $this->query = $this->createQueryBuilder('i')->join('i.product', 'p');
       return $this;
    }

    public function clearQuery()
    {
       $this->query = null;
       return $this;
    } 

    public function getResult(){
      $r = $this->query->getQuery()->getResult();
      $this->clearQuery();
      return $r;
    }

    public function filterByProductName( $productName )
    {

      if(!$this->query) $this->initNewQuery();

      $this->query->andWhere('p.name LIKE :name')->setParameter('name', '%'.$productName.'%');

      return $this;
    }

    public function filterByMinContenu( $contenu )
    {

      if(!$this->query) $this->initNewQuery();

      $this->query->andWhere('p.contenu > :contenu')->setParameter('contenu', $contenu);

      return $this;
    }

    public function filterByType( $type ){

      if(!$this->query) $this->initNewQuery();

      $this->query->andWhere('i.type = :type')->setParameter('type', $type);

      return $this;

    }      

}

这允许我做以下事情:

$ingredients = $em->getRepository('ingredient')->initNewQuery()->filterByType(4)->getResult();

$ingredients = $em->getRepository('ingredient')->initNewQuery()->filterByProductName('ell')->filterByMinContenu(10)->getResult();

这正是我想要的! 但是......我不是很喜欢它。 首先,这不是像findBy等默认方法的工作原理。这些都直接返回结果。因此,混合这两种行为似乎并不合适。 其次,当只调用filterByType方法然后返回结果时,查询将使用它不需要的连接。我想只有在需要的时候我才能找到一种方法来进行连接,但是再次,似乎没有。

关于如何做到这一点的任何想法清理简单?

1 个答案:

答案 0 :(得分:0)

快速回答而不进行测试:)

use Doctrine\ORM\EntityRepository;

class ingredientRepository extends EntityRepository
{
    private $query;

    private function initNewQuery()
    {
        $this->query = $this->createQueryBuilder('i');
    }

    public function findBy($filterArray)
    {
        $this->initNewQuery();
        if (array_key_exists('productName', $filterArray)) {
            $this->filterByProductName($filterArray['productName']);
        }
        if (array_key_exists('minContenu', $filterArray)) {
            $this->filterByMinContenu($filterArray['minContenu']);
        }
        if (array_key_exists('type', $filterArray)) {
            $this->filterByType($filterArray['type']);
        }
        return $this->query->getQuery()->getResult();
    }

    private function filterByProductName($productName)
    {
        $this->query->join('i.product', 'p');
        $this->query->andWhere('p.name LIKE :name')->setParameter('name', '%'.$productName.'%');
    }

    private function filterByMinContenu($contenu)
    {
        $this->query->andWhere('p.contenu > :contenu')->setParameter('contenu', $contenu);
    }

    private function filterByType($type)
    {
        $this->query->andWhere('i.type = :type')->setParameter('type', $type);
    }
}

呼叫:

$ingredients = $em->getRepository('ingredient')->findBy(['type'=>4]);

$ingredients = $em->getRepository('ingredient')->findBy(['productName'=>'ell', 'minContenu' => 10]);