我必须简单的实体:日志和用户。日志与实体具有ManyToOne关系。
Log:
type: entity
repositoryClass: LogRepository
id:
id:
type: integer
generator:
strategy: AUTO
fields:
message:
type: string
manyToOne:
user:
targetEntity: User
joinColumns:
user_id:
referencedColumnName: id
我的用例是显示日志列表以及有关该用户的一两个信息(例如,他的姓名和他的邮件)
如果使用该findall
方法,Symfony调试工具栏将向我显示Doctrine执行大量查询。一个查询给我日志,每个用户执行一个查询!当然不好,因为我可以查看成千上万的日志。我不想使数据库服务器超载。这个问题似乎很容易解决。但我搜索了一段时间,结果似乎是“不良做法”。
因此,我首先使用querybuilder在LogRepository类中编写了一个新方法:
public function getLog(){
$qb = $this->createQueryBuilder('l')
->select('l')
->innerJoin(
'ApplicationSonataUserBundle:User', 'u',
Expr\Join::WITH,'l.user = u.id')
;
return $qb->getQuery()->getResult();
}
我仍然有同样的问题。我已将我方法的选择参数更改为:
public function getLog(){
$qb = $this->createQueryBuilder('l')
->select('l','u')
->innerJoin('ApplicationSonataUserBundle:User','u',
Expr\Join::WITH,'l.user = u.id')
;
return $qb->getQuery()->getResult();
}
尤里卡?好的,我只有一个查询,但是我的方法也没有只返回Log,但是User也是如此。所以我的Twig模板崩溃了,因为我的循环中包含User,而不仅是Log。当这是一个用户时,我的视图崩溃,因为我想编写消息字段。(Log.message存在。但是User.message当然不是有效字段)
如果我再用循环更改一次方法来过滤结果,则效果很好:
public function getLog(){
$qb = $this->createQueryBuilder('l')
->select('l','u')
->innerJoin('ApplicationSonataUserBundle:User','u',
Expr\Join::WITH,'l.user = u.id')
;
//THE STRANGE LOOP
$results = array();
foreach ($qb->getQuery()->getResult() as $result){
if ($result instanceof Log){
$results[] = $result;
}
};
return $results;
}
我只有一个查询,这就是我要搜索的内容。我的树枝模板不会崩溃,因为我的数组仅包含Log。
那怎么了 它有效,但是我认为这不是最佳/最佳做法。
有人可以向我解释一个更好的方法,一个使用内部联接查询的更好实践,以最小化执行的查询并获得仅包含Log实例的ArrayCollection结果?
不必使用循环。尝试这样:
public function getLog(){
$qb = $this->createQueryBuilder('l')
->select('l','u')
->innerJoin('l.user', 'u');
$logs = $qb->getQuery()->getResult();
return $logs;
}
它仅应$logs
与已填充(获取加入)的关联用户一起返回。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句