使用内部联接时如何优化Doctrine查询的数量?

亚历山德拉·唐恩

我必须简单的实体:日志和用户。日志与实体具有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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章