Когда я пишу что-то вроде этого:
контроллер:
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 %}
каждый раз, когда я получаю доступ к термину, описанию, панели инструментов отладки, я показываю, что делает запрос к базе данных, чтобы получить каждый термин или другое отношение. Когда я обращаюсь к ним в контроллере, это не запросы db.
когда я пишу более подробный запрос 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();
...
}
И то же самое в twig для того же самого верхнего запроса:
{% 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();
Теперь либо в контроллере, либо в файле TWIG, если вы вызываете $action->getTerm()->getDescription()
или {{ action.getTerm.getDescription }}
он не будет выполнять отдельный запрос БД, потому что он был добавлен к вашему выбору, когда вы создали свой запрос.
Причина, по которой вы видите все эти запросы в TWIG
заключается в том, что вы обращаетесь к ним при запросе action.term
. Доктрина добавляет эти запросы к вам. Когда вы используете соединения, их запрашивают все в одном запросе. Это описано здесь: http://symfony.com/doc/current/book/doctrine.html#joining-related-records. Использование объединений рекомендуется избегать дополнительных запросов.