我在两个表(特许经营和玩家)之间建立了多对多关联,并使用附加表(franchise_players)构建。 我创建了三个实体:
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();
}
我认为特许经营实体的franchisePlayers字段(以及每个FranchisePlayer的de Player实体)将自动加载,但似乎这不是真的。
有可能吗?也许我在实体的映射中做错了什么?
谢谢!
编辑:昨天我确信查询效率最低,但现在我很怀疑。也许将这个复杂查询的结果加水化的成本大于水合选项2的查询的每个结果(在不同查询中查询每个特许经营者的玩家)的成本。你觉得怎么样?
答案 0 :(得分: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');