我正在使用ZF2和条令开发一个网站。我面临的问题是,我在代码中使用了Doctrine预定义的对象方法,如findAll()、findOneBy()、findBy()等。对于一些自定义操作,我为我的一个实体准备了一个自定义存储库。现在我无法访问预定义的方法。我已经使用findAll()方法编写了代码。但是在构建了一个存储库之后,我不能简单地访问findAll()方法。我如何既能访问我的自定义方法,又能访问条令定义的方法?
例如:
我使用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'));
为什么?我已经使用条令定义的方法编写了代码。我现在能做什么?
我相信您会收到这个错误,因为您已经重写了存储库的构造函数方法,但没有调用父构造函数,因此没有正确设置所需的参数。
我认为您的代码不正确,您可以使用下面的查询,而不是编写复杂的自定义对象。
$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();
您的方法中存在几个问题;
- 我认为尝试在实体存储库中访问服务定位器本身是个坏主意。您不应该需要存储库级别的服务容器
- 第二个细节是,当扩展任何类时,您需要签出、阅读并尊重父类的签名。在您的情况下,您正在覆盖父对象的
__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'));
我强烈建议在潜入深海之前仔细阅读文档中的"使用对象"部分。