内部联接如何使用Doctrine和Symfony2处理多对多关系

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有更好的方法吗?

M K*_*aid 8

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)