【发布时间】:2017-12-02 07:02:01
【问题描述】:
我正在编写一个 Symfony 应用程序,并且遇到了 Doctrine 实体急切加载的问题。 我不确定是否可以在同一个实体实例上加载多个一对多集合,同时保持良好的性能。
互联网上有很多例子,人们加载一个实体及其关系之一。 例如:
$user = $em->createQuery('
select a, au
from OctiviTestBundle:Article a
left join a.authorList au
where a.id = ?1')
->setParameter(1, $id)
->getOneOrNullResult();
但是如果我也想加载文章cmets,下面的请求检索到的结果太多(nb authors * nb cmets) => 组合爆炸
$user = $em->createQuery('
select a, au
from OctiviTestBundle:Article a
left join a.authorList au
left join a.commentList c
where a.id = ?1')
->setParameter(1, $id)
->getOneOrNullResult();
事实上,一旦从数据库中加载了一个对象,我就没有办法重用它。我不知道如何进行第二次查询以稍后加载更多部分。 例如:
$user = $em->createQuery('
select a, au
from OctiviTestBundle:Article a
left join a.authorList au
where a.id = ?1')
->setParameter(1, $id)
->getOneOrNullResult();
$em->LoadRelation($user, 'commentList');
$em->LoadRelation($user, 'commentList.author')
$em->LoadRelation($user, 'commentList.author.school');
... load any relation I want, while keeping only one root object.
我希望能够只有主实体实例变量,急切加载它的 2 个关系,然后遍历层次结构。 我知道我可以在不同的 php 变量中加载这两个列表,但我只想将“$user”变量传递给视图模板。
您对如何解决此问题有想法吗? 谢谢
我找到的唯一(棘手的)解决方案是在这个网站上:https://tideways.io/profiler/blog/5-doctrine-orm-performance-traps-you-should-avoid
$companies = array_map(function($employee) {
return $employee->getCompany();
}, $employees);
$repository = $entityManager->getRepository('Acme\Company');
$repository->findBy(['id' => $companies]);
2) 不要使用结果(删除 $companies 变量),但是现在 Doctrine 已经在缓存中获得了结果,所以当我执行 $employee->getCompany()->getName() 时,它不应该生成新的查询。
=> 不起作用:Doctrine 不会将结果放入缓存中以供以后重用。
【问题讨论】:
标签: php symfony doctrine-orm entity-relationship