doctrine教程16---使用 GROUP BY 在 1 个查询中获取和计数

Mario Sanchez

22 people read
Thumbnail

最后一个挑战。在主页上,我们有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();
    }

一切又完美的工作了

About Me

我是一位精通 Symfony 框架和 API Platform 的开发者,擅长构建高效、可扩展的 Web 应用程序和 API。 此外,我还具备 PrestaShop 模块开发经验,能够为您的电商平台定制功能,满足特定业务需求。