Symfony/Doctrine:如何减少SELECT-查询的数量? (多级关联实体;twig + jsonSerialize())

Symfony/Doctrine: How to reduce the num of SELECT-queries? (Multi-level associated entities; twig + jsonSerialize())

由于 的回答,我能够 减少 SELECT- 查询 第一级。不幸的是,关联的实体链接更深,例如:

Item -> Group -> Subscriber -> User -> username

存储库方法:

// ItemRepository
public function findAll() {
    return $this->createQueryBuilder('item')
                ->addSelect('groups')->join('item.groups', 'groups')
                ->getQuery()->getResult()
}

树枝模板:

{% for item in items %}
    {# Level: 0 #}
    Name: {{ item.name }}<br/>
    Groups:<br/>
    <ul>
        {# Level: 1 #}
        {% for group in item.groups %}
           <li>{{ group.name }}<br/>
               <ol>
               {# Level: 2 #}
               {% for subscriber in group.subscribers %}
                   {# Level: 3 #}
                   <li>{{ subscriber.user.username }}</li>
               {% endfor %}
               </ol>
           </li>
        {% endfor %}
    </ul>
{% endfor %}

注意: 我正在使用 jsonSerialize 准备 JSON 数据,其中还包括多级迭代。

use JsonSerializable;
// ...

class Item implements JsonSerializable {

    // ...

    public function jsonSerialize() {
        $subscribers = array();
        $groups      = $this->getGroups();
        foreach ($groups as $group) {
            foreach ($group->getSubscribers() as $subscriber) {
                $subscribers[$subscriber->getId()] = array(
                    'userId'   => $subscriber->getUser()->getId();
                    'username' => $subscriber->getUser()->getUsername();
                );
            }
        }

        return array(
            'id'          => $this->getId(),
            'subscribers' => $subscribers
            // ...
        );
    }
}

有没有办法加入更深层次的关联数据以及减少SELECT-[=的数量33=]再次查询(对于 twig 和 jsonSerialize())

我建议您更改特定查询中的提取模式,如文档中here所述。

所以您可以如下描述您的查询:

$qb =  $this->createQueryBuilder('item')
                ->addSelect('groups')->join('item.groups', 'groups'); // Not necessary anymore

        $query = $qb->getQuery();
        // Describe here all the entity and the association name that you want to fetch eager
        $query->setFetchMode("YourBundle\Entity\Item", "groups", ClassMetadata::FETCH_EAGER);
        $query->setFetchMode("YourBundle\Entity\Groups", "subscriber", ClassMetadata::FETCH_EAGER);
        $query->setFetchMode("YourBundle\Entity\Subscriber", "user", ClassMetadata::FETCH_EAGER);
        ...

return $qb->->getResult();

注意:

Changing the fetch mode during a query is only possible for one-to-one and many-to-one relations.

希望对您有所帮助