Published on

doctrine教程10---选择特定字段

原创文章,转载时需取得本人同意并注明来源
Authors
  • doctrine教程10---选择特定字段
    Name
    langziyang
    Twitter

现在我们可以选择想要的任何数据,但返回的是一个数组,在开发过程中其实用实体对象是最方便的,幸运的是,Doctrine 为我们提供了一种简单的方法来改善这种情况:我们查询我们想要的数据……但告诉它给我们一个对象。

首先我们需要创建一个新类来保存查询中的数据,我们创建一个CategoryFortuneStats,放在src/Model中

该类的全部目的是保存来自该特定查询的数据。因此,为了简单起见,添加一个带有一些 public 属性的 public function __construct() : public int $fortunesPrinted 、 public float $fortunesAverage 和 public string $categoryName 。

<?php

namespace App\Model;

class CategoryFortuneStats
{
    public function __construct(
        public int    $fortunesPrinted,
        public float  $fortunesAverage,
        public string $categoryName,
    )
    {
    }
}

我们可以在存储库中返回new CategoryFortuneStats() 并将每个键传递到其中,但是Doctrine有一个更好的方法

  public function countNumberPrintedForCategory(Category $category): array
    {
        $result = $this->createQueryBuilder('fortuneCookie')
            ->select(sprintf(
                'NEW %s(
                    SUM(fortuneCookie.numberPrinted) AS fortunesPrinted,
                    AVG(fortuneCookie.numberPrinted) fortunesAverage,
                    category.name
                )',
                CategoryFortuneStats::class
            ))
            ->innerJoin('fortuneCookie.category', 'category')
            ->andWhere('fortuneCookie.category = :category')
            ->setParameter('category', $category)
            ->getQuery()
            ->getSingleResult();
        dd($result);
        return $result;
    }

其实就是把查询结果复制给一个新的CategoryFortuneStats对象,一目了然,但是如果我们刷新页面会出现一个错误:

[Syntax Error] line 0, col 96: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got 'AS'

这里不允许再使用别名,因为构造函数已经自动按位传参了,删除fortunesPrinted和fortunesAverage 最终代码为:

public function countNumberPrintedForCategory(Category $category): CategoryFortuneStats
    {
        $result = $this->createQueryBuilder('fortuneCookie')
            ->select(sprintf(
                'NEW %s(
                    SUM(fortuneCookie.numberPrinted),
                    AVG(fortuneCookie.numberPrinted),
                    category.name
                )',
                CategoryFortuneStats::class
            ))
            ->innerJoin('fortuneCookie.category', 'category')
            ->andWhere('fortuneCookie.category = :category')
            ->setParameter('category', $category)
            ->getQuery()
            ->getSingleResult();
        return $result;
    }