最后一个挑战。在主页上,我们有N+1个查询。其中一个用于获取类别...还有 N个用于获取这 N 个类别中每一类别的计数。
因为数据量小,所以你不必要担心性能问题,直到数据越来越大......
我们修改一下CategoryRepository中findAllOrdered方法
public function findAllOrdered(): array
{
$qb
= $this->createQueryBuilder('category')
->addOrderBy('category.name', Criteria::DESC)
->addSelect('COUNT(fortuneCookie.id) AS fortuneCookiesTotal')
->leftJoin('category.fortuneCookies', 'fortuneCookie')
->addGroupBy('category.id');
$query = $qb->getQuery();
return $query->getResult();
}
然后修改homepage.html.twig
{% for categoryData in categories %}
{% set category = categoryData[0] %}
<a class="bg-orange-400 hover:bg-orange-500 text-white text-center rounded-full p-4" href="{{ path('app_category_show', {'id': category.id}) }}">
<span class="fa {{ category.iconKey }}"></span> <span class="font-bold text-lg">{{ category.name }}</span> ({{ categoryData.fortuneCookiesTotal }})
</a>
{% else %}
<h3>Hmm... there don't seem to be any fortunes</h3>
{% endfor %}
刷新,只有一次查询了,但是数据结构发生了变化,其实也是无伤大雅的,但是如果你可能会喜欢我下面的做法:
例如,我们可以创建一个名为 CategoryWithFortuneCount 的新类,它具有两个属性 - $category 和 $fortuneCount 。在此存储库方法中,我们可以循环 $query->getResults() 并为每个对象创建一个 CategoryWithFortuneCount 对象。最终,我们的方法将返回一个 CategoryWithFortuneCount 数组。返回一个对象数组比一个数组数组要好得多......带有一些随机 0 索引。
现在我们去搜索,会得到一个错误:
Impossible to access a key "0" on an object of class "App\Entity\Category" that does not implement ArrayAccess interface.
因为我们搜索方法里并没有新的addSelect和groupBy,依然返回的是Category对象数组,我们先创建一个addGroupByCategory方法:
private function addGroupByCategory(QueryBuilder $qb = null): QueryBuilder
{
return ($qb ?? $this->createQueryBuilder('category'))
->addSelect('COUNT(fortuneCookie.id) AS fortuneCookiesTotal')
->leftJoin('category.fortuneCookies', 'fortuneCookie')
->addGroupBy('category.id');
}
public function findAllOrdered(): array
{
$qb
= $this->addGroupByCategory()
->addOrderBy('category.name', Criteria::DESC);
$query = $qb->getQuery();
return $query->getResult();
}
public function search(string $term)
{
$termList = explode(' ', $term);
$qb = $this->addGroupByCategory()
->andWhere('category.name LIKE :searchTerm OR category.name IN(:termList) OR category.iconKey LIKE :searchTerm OR fortuneCookie.fortune LIKE :searchTerm')
->setParameter('searchTerm', '%' . $term . '%')
->setParameter('termList', $termList);
$query = $qb->getQuery();
return $query->getResult();
}
一切又完美的工作了