如何在自定义存储库之后访问Doctrine定义的方法?

时间:2015-06-22 10:31:20

标签: php symfony zend-framework2 doctrine

我正在使用ZF2和Doctrine开发一个网站。我面临的问题是我在我的代码中使用了诸如findAll(),findOneBy(),findBy()等Doctrine预定义对象方法。对于一些自定义操作,我为我的一个实体准备了一个自定义存储库。现在我无法访问预定义的方法。我已经使用findAll()方法编写了代码。但是在构建存储库之后,我不能简单地访问findAll()方法。如何同时使用Doctrine定义的方法访问自定义方法?

例如:

我正在使用像这样的findOneBy():

$udata = $this->em()->getRepository('Application\Entity\Usermain')->findOneBy(array('userEmail' => 'subh.laha@gmail.com'));

现在我已经准备好了UsermainRepository,如下所示:

namespace Application\Entity\Repositories;

use Doctrine\ORM\EntityRepository;
use Doctrine\Common\Persistence\ObjectRepository;

class UsermainRepository extends EntityRepository
{   
    protected $sl;

    public function __construct($sl){

        $this->sl = $sl;    
    }

    public function customFind($arr)
    {
        $qb = $this->sl->createQueryBuilder();

        $whereStr = '';

        if(count($arr)){

            foreach($arr as $kvarr=>$varr){

                $whereStr .= "u.$kvarr = '".$varr."'";  
            }   
        }

        $qry = $qb->select('u')
                   ->from('Application\Entity\Usermain','u')
                   ->where($whereStr)
                   ->getQuery()
                   ->getResult(); 

        return $qry;
    }
}

现在我可以访问

$udata = $this->em()->getRepository('Application\Entity\Usermain')->customFind(array('userEmail' => 'subh.laha@gmail.com'));

但不是

$udata = $this->em()->getRepository('Application\Entity\Usermain')->findOneBy(array('userEmail' => 'subh.laha@gmail.com'));

为什么呢?我已经使用doctrine定义的方法编写代码。我现在能做什么?

3 个答案:

答案 0 :(得分:2)

我相信您收到此错误是因为您已覆盖了存储库的构造函数方法但未调用父构造函数,因此未正确设置所需的参数。

答案 1 :(得分:2)

您的方法存在几个问题;

  • 我认为尝试在实体存储库中访问服务定位器本身是个坏主意。您不应该在存储库级别中需要服务容器。
  • 第二个细节是,在扩展任何课程时,您需要签出,阅读并尊重父母的签名。在您的情况下,您将覆盖父级__construct。拨打parent::__construct()似乎是一种解决方案,但事实并非如此。您很快就会意识到,您还需要一个自定义存储库工厂,以便在保持当前功能的同时将其他参数传递给构造函数。没办法。
  • 这比其他人更重要:您认为$this->sl->createQueryBuilder()返回查询构建器实例。理论上似乎工作,但$this->sl不是服务定位器,服务定位器不知道有关查询构建器的任何信息,它只是传递给构造函数的EntityManager实例。

试试这个:

<?php
namespace Application\Entity\Repositories;

use Doctrine\ORM\EntityRepository;

class UsermainRepository extends EntityRepository
{

    public function customFind($arr)
    {
        // Just pass an alias for your entity
        $qb = $this->createQueryBuilder('u');

        $whereStr = '';

        if (count($arr)) {
            foreach ($arr as $kvarr => $varr) {
                $whereStr .= "u.$kvarr = '".$varr."'";
            }
        }

        return $qb->where($whereStr)
                  ->getQuery()
                  ->getResult();
    }
}

最后,在您的Application\Entity\Usermain实体中,由于您不想使用默认EntityRepository,因此您还需要告知自定义存储库到教义:

namespace Application\Entity;

/**
 * @ORM\Entity(repositoryClass="Application\Entity\Repositories\UsermainRepository")
 */
class Usermain
{

}

现在,在您的控制器(或服务)级别,您可以测试:

$em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
$repo = $em->getRepository('Application\Entity\Usermain');
// repo is a UsermainRepository instance
// this should work:
$udata = $repo->customFind(array('userEmail' => 'subh.laha@gmail.com'));
// this should also work
$udata = $repo->findOneBy(array('userEmail' => 'subh.laha@gmail.com'));

我强烈建议您在深入了解之前仔细阅读文档的Working With Objects部分。

答案 2 :(得分:2)

我认为您的代码不正确,您可以使用以下查询而不是编写复杂的自定义对象。

$query = $this->getEntityManager()->createQueryBuilder()
                    ->select('U.id,U.name')  
                    ->from('Application\Entity\StudentClass', 'U')
                    ->where('U.pkStudentClass = :pkStudentClass')
                    ->setParameter('pkStudentClass', 1)
                    ->setMaxResults(20); 
                    ->orderBy('id', 'DESC') 
                    ->getQuery();

 $result = $query->getScalarResult();