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.
希望对您有所帮助
由于 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.
希望对您有所帮助