php - Symfony 查询生成器将所有结果添加到结果集中

标签 php mysql symfony

我试图找出所有艺术家列表,他们是否具有角色,但我当前的查询仅显示在数据库中具有角色的艺术家姓名:

这是我的查询:

$em = $this->getDoctrine()->getManager();



    $entities = $em->getRepository('MyAppBundle:Artist')
        ->createQueryBuilder('c')
        ->select('c.id, c.name, c.sex, c.priority, c.bday, c.bmonth, c.byear,IDENTITY(co.content) as work')
        ->addSelect('IDENTITY(co.content) as work, IDENTITY(co.role) as roles')
        ->innerJoin('c.cast_and_crews', 'co')
        ->getQuery()
        ->getArrayResult();

    foreach ($entities as &$artist) {
        $role = $em->getRepository('MyAppBundle:Role')
            ->createQueryBuilder('e')
            ->select('e.name')
            ->where('e.id = :id')
            ->setParameter('id', $artist['roles'])
            ->getQuery()
            ->getResult();

        $artist['role'] = ($role[0]['name']);

而且它的查询时间也非常非常糟糕。我的表中有 9000 行,此查询查询我从探查器中看到的所有 9000 行,花费了 1000 多毫秒。此外,在此查询中仅显示一个角色,但一位艺术家可能具有多个角色,如何将其保留在 artis['role'] 中?

谁能提出一个好的解决方案吗?

最佳答案

使用leftJoin()而不是innerJoin()

假设 Country 实体有许多 League 实体。此外,有些国家没有任何联赛。

协会:

class Country
{
    protected $id;

    /**
     * @ORM\OneToMany(
     *      targetEntity="League",
     *      mappedBy="country",
     *      cascade={"persist", "remove"}
     * )
     */
    protected $league;
}

class League
{
    protected $id;

    /**
     * @ORM\ManyToOne(
     *      targetEntity="Country",
     *      inversedBy="league"
     * )
     * @ORM\JoinColumn(
     *      name="country_id",
     *      referencedColumnName="id",
     *      onDelete="CASCADE",
     *      nullable=false
     * )
     */
    protected $country;
}

示例查询:

public function findAll()
{
    return
        $this
            ->createQueryBuilder('c')
            ->select('c, l')
            ->leftJoin('c.league', 'l')
            ->orderBy('c.name', 'ASC')
            ->getQuery()
            ->getResult();
}

上面的示例将返回与国家/地区和联赛相关的数据,因此您可以看到,我没有像您一样运行循环来从其他实体中选择数据,因为查询已经返回了我需要的所有内容。

Controller 中的结果:

如您所见,结果也包括联赛。

$country = $repo->findAll();

foreach ($country as $c) {

    echo $c->getId() . ' -> ' . $c->getName() . PHP_EOL;

    foreach ($c->getLeague() as $l) {
        echo $l->getId() . ' -> ' . $l->getName() . PHP_EOL;
    }
}

现在您可以继续为自己创建一个ONLY ONE查询,就像我上面所做的那样。

我想你的会是这样的:

public function findAll()
{
    return
        $this
            ->createQueryBuilder('a')
            ->select('a, r')
            ->leftJoin('a.role', 'r')
            ->orderBy('a.name', 'ASC')
            ->getQuery()
            ->getResult();
}

$artist = $repo->findAll();

foreach ($artist as $a) {

    echo $a->getId() . ' -> ' . $a->getName() . PHP_EOL;

    foreach ($a->getRole() as $r) {
        echo $r->getId() . ' -> ' . $r->getName() . PHP_EOL;
    }
}

关于php - Symfony 查询生成器将所有结果添加到结果集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30679272/

相关文章:

带摘要的 php curl 返回两个响应

php - 选择时找不到 Symfony3 Doctrine 多对多列

php - lessphp 中的多嵌套、多 block 混合

php - Mail-Tester.com : Freemail in Reply-To, 但不是来自

php - 如何从字符串格式的列中获取最后插入的行值?

MySql 查询从相关表中获取用户电子邮件

php - 找不到 Symfony 3 方法 'guessExtension()' 和 'move()'

php - Symfony 3 在 FormType 中注入(inject)容器

php - 无法从 MySQL 中提取值

mysql - 从 MySQL 中的上一行中选择多列