Cha*_*yer 6 php symfony doctrine-orm
如果我有一个关联的实体是一个集合,你在获取时有什么选择?
例如,假设我有一个$view具有此定义的实体:
/**
* @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", mappedBy="entity")
* @ORM\OrderBy({"timeMod" = "DESC"})
*/
protected $versions;
public function getVersions() {
return $this->versions;
}
Run Code Online (Sandbox Code Playgroud)
我希望得到与实体相关的所有版本,如下所示:
$view->getVersions();
Run Code Online (Sandbox Code Playgroud)
这将返回一个集合.大.但是有可能采用该集合并按标准过滤它,例如比某个日期更新吗?或者按一些(其他)标准订购?
或者此时您只是希望对存储库进行查询:
$versions = $em->getRepository("GutensiteCmsBundle:View\ViewVersion")->findBy(array(
array(
'viewId', $view->getId(),
'timeMod', time()-3600
)
// order by
array('timeMod', 'DESC')
));
Run Code Online (Sandbox Code Playgroud)
最新版本的Doctrine中有一个令人惊讶的未知功能,它使这些查询更容易.
它似乎没有名称,但您可以在9.8过滤集合的Doctrine文档中阅读它.
集合具有过滤API,允许从集合中分割部分数据.如果尚未从数据库加载集合,则过滤API可以在SQL级别上工作,以便对大型集合进行优化访问.
在您的情况下,您可以在您的View实体上编写这样的方法.
use Doctrine\Common\Collections\Criteria;
class View {
// ...
public function getVersionsNewerThan(\DateTime $time) {
$newerCriteria = Criteria::create()
->where(Criteria::expr()->gt("timeMod", $time));
return $this->getVersions()->matching($newerCriteria);
}
}
Run Code Online (Sandbox Code Playgroud)
这将做两件事之一:
这真的很棒,因为将存储库方法连接到您的视图通常是混乱的并且容易中断.
我也喜欢@ igor-pantovic的回答,虽然我已经看到这种方法会导致一些有趣的错误.
我个人会避免直接在注释上使用 order by 。是的,您应该执行查询,就像您使用原始 SQL 而不使用 Doctrine 一样。
然而,我不会在那时甚至之前这样做。根据您的具体情况,我将创建一个ViewRepository类:
class ViewRepository extends EntityRepository
{
public function findWithVersionsNewerThan($id, \DateTime $time)
{
return $this->createQueryBuilder('view')
->addSelect('version')
->join('view.versions', 'version')
->where('view.id = :id')
->andWhere('version.timeMod > :time')
->setParameter('time', $time)
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult();
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
$yourDateTime = // Calculate it here ... ;
$view = $em->getRepository("GutensiteCmsBundle:View\ViewVersion")->findWithVersionsNewerThan($yourDateTime);
$versions = $view->getVersions(); // Will only contain versions newer than datetime provided
Run Code Online (Sandbox Code Playgroud)
我在这里直接从头开始编写代码,如果出现一些语法或方法命名错误,我很抱歉。