【问题标题】:Symfony/Doctrine: How to reduce the num of SELECT-queries? (Multi-level associated entities; twig + jsonSerialize())Symfony/Doctrine:如何减少 SELECT 查询的数量? (多级关联实体;twig + jsonSerialize())
【发布时间】:2015-07-29 17:54:51
【问题描述】:

由于my last question 的回答,我能够在第一级减少 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-查询的数量(对于 twig 和 jsonSerialize())

【问题讨论】:

  • 恭喜!您发布了 10 000 个问题!

标签: php symfony orm doctrine-orm twig


【解决方案1】:

我建议您在特定查询中更改获取模式,如文档中的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();

注意:

在查询期间更改获取模式仅适用于一对一 和多对一关系。

希望有帮助

【讨论】:

  • 非常感谢!正是我想要的,因为我想在我的实体中避免 fetch='EAGER'。再次注意:it's not working for many-to-many!
猜你喜欢
  • 1970-01-01
  • 2015-12-23
  • 2014-09-30
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多