1
我在两张表(特许经营和玩家)之间建立了一个多对多的关联,用另外一张表(franchise_players)构建。 我已创建了三个实体:学说2:查询多对多关联的有效方式
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();
另一种解决方案是让所有的特许经营权,然后执行LEFT JOIN来获取每一个特许经营相关的球员:
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();
}
我认为特许经营实体(每FranchisePlayer也去球员实体)的franchisePlayers领域将自动加载,但似乎这是不正确的。
是否可以做到这一点?也许我在我的实体的映射中做错了什么?
谢谢!
编辑:昨天我确信越少查询效率最高,但现在我怀疑。也许这种复杂查询的结果水成本大于选项2查询的每个结果的花费(在不同查询中查询每个特许经营者的球员)。你怎么看?
我已经检查了您的建议,但此查询返回不同对象的数组。第一个元素是特许经营,但第二个元素是特许经营者,第三个是玩家,第四个是特许经营者。也就是说,我只用一个查询就能得到所需的所有对象(太棒了!),但它们混合在同一个数组中。 – TxusMa
只是为了聚焦这个问题:我想要获得已经加载的franchisePlayers字段的一系列特许经营权(以避免额外的查询)。而且这些特许玩家对象应该也加载了玩家领域。 – TxusMa
再次检查。所显示的查询将返回特许经营对象列表。 – Cerad