从2个连接中检索数据并使用Symfony 2检索每一行的级别?

时间:2015-12-29 23:53:35

标签: php mysql database symfony

我有一个包含两个JOIN的表:广告,技能和每行的级别:

enter image description here

我可以通过以下方式获取数据:

$listAdvertSkills = $em
      ->getRepository('OCPlatformBundle:AdvertSkill')
      ->findBy(array('advert' => $advert))
    ;

如何加入"加入"方法?像这样的东西?

public function getSkillsForThisAdvert($id){
    $qb = $this
            ->createQueryBuilder('a')
            ->join('a.advert', 'adv')
            ->where('adv.id', $id) //addSelect here?
            ->join('a.skill', 'sk');
            ->addSelect('sk');
    return $qb->getQuery()->getResult();
}

另外,如果是"类别"的数组在每个广告中,如果我想得到:
所有类别,
所有来自一个类别的广告,
一个广告和关卡所需的所有技能,

请求是什么?

并在另一页,同样但来自技巧:
所有技能,
所有具有这些技能的广告,
来自一个广告的所有类别。

只是要了解正确的方法,它不适用于任何工作。

由于

1 个答案:

答案 0 :(得分:1)

您是对的 - 第一种方法可行,但如果您想从任何关联实体检索数据,则会运行其他查询。如果列出大量行,则可能会导致数十个其他查询,因此使用JOIN并预先选择其他实体是一种很好的做法。

有关进一步说明 - 如果您在查询构建器中加入广告和技能表而不执行任何其他操作,则SQL查询将加入表,但不会从中选择任何信息。因此,如果您稍后尝试访问它们,则Doctrine必须调用更多SQL查询才能检索该信息。这就是addSelect电话很重要的原因。那些告诉Doctrine(和SQL)检索关联实体的所有信息。例如,如果广告有5种额外技能,那么您的SQL将返回5行,但是Doctrine会将其水合成5个技能实体的数组(或Doctrine ArrayCollection),这些实体可以从单个Advert对象访问返回。

您的QueryBuilder可能如下所示:

public function getSkillsForThisAdvert($id)
{
    $qb = $this
        ->createQueryBuilder('a')
        ->addSelect('adv')
        ->addSelect('sk')
        ->join('a.advert', 'adv')
        ->join('a.skill', 'sk');
        ->where('a.id = :identifier')
        ->setParameter(':identifier', $id);

    return $qb->getQuery()->getResult();
}

您也可以将Advert对象作为$advert传递给您的函数,并将查询构建器调用更改为->where('a = :advert')->setParameter('advert', $advert);

我可能还建议将函数名称更改为getSkills,因为您已经传递了所需的广告对象。

如果您不喜欢使用QueryBuilder,您只需使用看起来更像SQL的DQL Queries(而不是先使用QueryBuilder构建,然后使用getQuery检索查询)。只要您的实体与其相应的关联实体正确定义,Doctrine将为您完成大部分繁重工作。如果你想选择一个广告及其所有相关技能,Doctrine已经为你做了一个工作,你可以为数组或ArrayCollection中的相应技能对象检索一个对象,而不是一个返回多行的原始SQL语句。重复,并要求你自己处理。

您还可以执行以下操作,而不是多个addSelect语句:

->select(array('a', 'adv', 'sk'))

此外,如果您要有多个WHERE条件,请将where更改为addWhere - 实际上,最好始终使用addWhere