访问 twig 模板中的对象时的其他数据库请求


Additional database requests when accessing object relates in twig template

当我写这样的东西时:

控制器:

public function listAction() {
    $actions = $this->getDoctrine()->getRepository('AcmeDemoBundle:Action')->findAll();
    return $this->render('AcmeDemoBundle:Admin:action/list.html.twig', 
            array('actions' => $actions));    
}

树枝模板:

        {% for action in actions %}
          ..........
            {% for descr in action.term.description %}
                <dd class="l-margin">{{ descr.text }}</dd>
            {% endfor %}

每次我访问术语、描述、调试工具栏时,都会向我显示对数据库的请求,以获取每个术语或其他关系。当我在控制器中访问它们时,没有此数据库请求。

当我编写更详细的 DQL 查询时,如下所示:

    $qb->select('action, term, descr')
        ->from('AcmeDemoBundle:Action', 'action')
        ->join('action.term', 'term');
        ->join('term.description', 'descr');

所有其他请求都将消失。一定是这样吗?

它就是这样; 表示在 TWIG 文件或控制器中,如果您从查询结果调用相关对象,则哪些对象未添加到您的选择中将获取数据库查询。 例如:

$actions = $this->getDoctrine()->getRepository('AcmeDemoBundle:Action')->findAll();
foreach ($actions as $action) {
   print $action->getTerm()->getDescription();
   ...
}
对于

相同的顶级查询,在树枝中也是如此:

{% for action in actions %}
     <dd class="l-margin">{{ action.getTerm.getDescription }}</dd>

这些排名靠前的示例将触发数据库查询,因为相关实体不会添加到选择中。将相关实体添加到选择查询的相同选择将减少执行的数据库查询的数量,但将导致选择相乘的行和列进行连接,具体取决于查询中使用的连接类型,例如:

$result = $em->createQueryBuilder('A')
   ->addSelect('A.term')
   ->join('A.term', 'T')
   ->getQuery()
   ->getResult();

现在,如果您调用$action->getTerm()->getDescription(){{ action.getTerm.getDescription }},则在控制器或TWIG文件中,它不会执行单独的数据库查询,因为它是在构建查询时添加到您的选择中。

您在TWIG中看到所有这些查询的原因是您在请求action.term时正在访问它们。教义为您添加了这些查询。使用联接时,将在一个查询中请求所有联接。这记录在这里 - http://symfony.com/doc/current/book/doctrine.html#joining-related-records。建议使用联接以避免额外的查询。