pin*_* af 10 php mysql doctrine symfony doctrine-orm
我最近解决了查询ManyToMany关系连接表的问题,解决方案与此答案相同,并且想知道它是如何工作的.假设我和ManyToMany之间有一个简单的关系,会有一个表格会自动在这里创建groupsteamgroups_team
团体实体
/**
* Groups
*
* @ORM\Table(name="groups")
* @ORM\Entity(repositoryClass="AppBundle\Model\Repository\GroupsRepository")
*/
class Groups {
/**
* @ORM\ManyToMany(targetEntity="Team", inversedBy="group")
*/
protected $team;
public function __construct() {
$this->team = new ArrayCollection();
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="groupname", type="string", length=255)
*/
private $groupname;
//obligatory getters and setters :)
Run Code Online (Sandbox Code Playgroud)
团队实体
/**
* Team
*
* @ORM\Table(name="team")
* @ORM\Entity(repositoryClass="AppBundle\Model\Repository\TeamRepository")
*/
class Team {
/**
* @ORM\ManyToMany(targetEntity="Groups", mappedBy="team")
*/
protected $group;
public function __construct(){
$this->group = new ArrayCollection();
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="teamname", type="string", length=255)
*/
private $team;
//[setters and getters here]
Run Code Online (Sandbox Code Playgroud)
为了得到一个组中的所有团队,我将不得不查询groups_teamtable.i将直接查询只在mysql中的表,但在symfony我必须这样做
$groups = $em->getRepository("AppBundle\Model\Entity\Groups")->findBy(array('tournament' => $tournament->getId()));
//get all teams with group id in groups_team table
foreach ($groups as $group) {
$teamsingroup = $em->getRepository("AppBundle\Model\Entity\Team")->createQueryBuilder('o')
->innerJoin('o.group', 't')
->where('t.id = :group_id')
->setParameter('group_id', $group->getId())
->getQuery()->getResult();
echo "</b>".$group->getGroupname()."</b></br>";
foreach ($teamsingroup as $teamingroup) {
echo $teamingroup->getTeam()."</br>";
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释它innerJoin是如何工作的,这背后的概念是什么,可能需要一些文档来了解这一点.使用symfony和doctrine有更好的方法吗?
ManyToMany当您构建DQL(学说查询)原则时,根据您定义为注释的关系的性质自动连接联结表,因此在2个实体之间使用涉及通常称为此类关系中的联结表的第三个表,因此请考虑您的查询
$teamsingroup = $em->getRepository("AppBundle\Model\Entity\Team")
->createQueryBuilder('o')
->innerJoin('o.group', 't')
Run Code Online (Sandbox Code Playgroud)
您正在加入Team实体,Group实体innerJoin('o.group')部分o是Team实体的别名,并且o.group是指在Team名为的实体中定义的属性group.
/**
* @ORM\ManyToMany(targetEntity="Groups", mappedBy="team")
*/
protected $group;
Run Code Online (Sandbox Code Playgroud)
其中有一个ManyToMany为此类关系定义的注释doctrine首先使用联结表连接您的团队表,然后将您的联结表与groups表连接,结果SQL将类似于
SELECT t.*
FROM teams t
INNER JOIN junction_table jt ON(t.id = jt.team_id)
INNER JOIN groups g ON(g.id = jt.group_id)
WHERE g.id = @group_id
Run Code Online (Sandbox Code Playgroud)
另一个与你为每个团队组建团队的方式有关,你可以通过createQueryBuilder在循环中排除部分来最小化你的代码,一旦你定义了团队属性,ArrayCollection即$this->team = new ArrayCollection();在每个组对象上,你将通过调用组上的getTeam()函数获得与该特定组相关联的团队集合对象类似于下面的代码.
foreach ($groups as $group) {
$teamsingroup = $group->getTeam();
echo "</b>".$group->getGroupname()."</b></br>";
foreach ($teamsingroup as $teamingroup) {
echo $teamingroup->getTeam()."</br>";
}
}
Run Code Online (Sandbox Code Playgroud)