Doctrine orm 原则2:查询多对多关联的有效方法
我在两个表(特许经营和玩家)之间有一个多对多的关联,它是用一个额外的表(特许经营和玩家)构建的。 我创建了三个实体:Doctrine orm 原则2:查询多对多关联的有效方法,doctrine-orm,dql,Doctrine Orm,Dql,我在两个表(特许经营和玩家)之间有一个多对多的关联,它是用一个额外的表(特许经营和玩家)构建的。 我创建了三个实体: class Franchise { ... /** * * @var ArrayCollection * * @ORM\OneToMany(targetEntity="NBA\Entity\FranchisePlayer", mappedBy="franchise") */ private $fran
class Franchise
{
...
/**
*
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="NBA\Entity\FranchisePlayer", mappedBy="franchise")
*/
private $franchiseplayers;
...
}
class Player
{
/* some fields */
}
class FranchisePlayers
{
...
/**
* @var \NBA\Entity\Player
*
* @ORM\ManyToOne(targetEntity="NBA\Entity\Player")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="playerId", referencedColumnName="id")
* })
*/
private $player;
/**
* @var \NBA\Entity\Franchise
*
* @ORM\ManyToOne(targetEntity="NBA\Entity\Franchise")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="franchiseId", referencedColumnName="id")
* })
*/
private $franchise;
}
我的目标是获得所有与他们相关的球员的特许经营权
显而易见的解决方案很简单,但效率不高:
Get all franchises
foreach $franchise
$franchise->getFranchisePlayers()
foreach $franquisePlayer
$franquisePlayer->getPlayer()->getFullName();
另一种解决方案是获得所有特许经营权,然后执行左联合,以获得每个特许经营权的相关玩家:
Get all franchises
foreach $franchise
public function getCurrentPlayers(Franchise $franchise) {
$qb = $this->entityManager->createQueryBuilder();
$qb->select(array('p'))
->from('NBA\Entity\Player', 'p')
->leftjoin('NBA\Entity\FranchisePlayer','f','WITH','f.player=p')
->where('f.franchise = ?1')
->orderBy('p.surname','ASC')
->setParameter(1,$franchise);
$query = $qb->getQuery();
return $query->getResult();
}
通过这种方式,我们减少了查询的数量
我的问题是,我是否可以通过这样一个查询来实现我的目标:
public function getFranchisesWithPlayers() {
$qb = $this->entityManager->createQueryBuilder();
$qb->select(array('f'))
->from('NBA\Entity\Franchise', 'f')
->leftJoin('NBA\Entity\FranchisePlayer','fp','WITH','fp.franchise=f')
->leftJoin('NBA\Entity\Player','p','WITH','fp.player=p')
->orderBy('f.name')
->addOrderBy('p.surname');
$query = $qb->getQuery();
return $query->getResult();
}
我认为特许经营实体的特许经营玩家字段(以及每个特许经营玩家的de-Player实体)将自动加载,但这似乎不是真的
有可能吗?也许我在实体的映射中做错了什么
谢谢大家!
编辑:昨天我确信少查询的查询效率最高,但现在我怀疑。可能这个复杂查询结果的水合成本大于选项2查询结果的水合成本(针对不同查询中每个特许权的玩家的查询)。您觉得怎么样?文档展示了如何创建查询。也许值得一看。比如:
$qb->select('franchise,franchisePlayer,player')
->from('NBA\Entity\Franchise', 'franchise')
->leftJoin('franchise.franchisePlayers','franchisePlayer')
->leftJoin('franchisePlayer.player','player')
->orderBy('franchise.name')
->addOrderBy('player.surname');
我已经检查了你的建议,但是这个查询返回一个不同对象的数组。第一个要素是特许经营,但第二个要素是特许经营球员,第三个要素是球员,第四个要素也是特许经营球员。也就是说,我在一个查询中就得到了我想要的所有对象(太棒了!),但混合在同一个数组中。只是为了集中问题:我想获得一个特许权数组,其中特许权玩家字段已经加载(为了避免额外的查询)。这些玩家对象也应该加载玩家字段。再次检查。如图所示的查询将返回特许经营对象列表。谢谢,你完全正确。我没有正确构建查询。您认为只执行一个查询更有效,还是对每个特许经营权执行一个查询更好,以便获得相关玩家?对于这些类型的查询,当您知道需要所有附加信息时,单个查询通常是最好的。当你有很多很多关系的时候,事情可能会开始变慢。但每个案例都会有所不同。