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

时间:2016-01-19 10:33:50

标签: php mysql symfony doctrine-orm doctrine

我最近解决了查询ManyToMany关系连接表的问题,解决方案与此answer相同,并且想知道它是如何工作的。 假设我在ManyToManygroups之间有一个简单的team关系,会有一个groups_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 :)

团队实体

/**
 * 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]

为了获得一个组中的所有团队,我将不得不查询groups_team table.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>";
            }
        }

有人可以向我解释innerJoin是如何运作的,以及这背后的概念是什么,可能需要一些文档来了解这一点。使用symfony和doctrine有更好的方法吗?

2 个答案:

答案 0 :(得分:8)

在2个实体之间使用//placed under class ViewController: UIViewController var index = 0 @IBOutlet weak var picture: UIImageView! var myArray:[String] = ["img1", "img2", "img3", "img4", "img5"] //placed under override func didReceiveMemoryWarning() & super...() @IBAction func pictureSwipe(sender: UISwipeGestureRecognizer) { let pictureString:String = self.myArray[index] self.picture.image = UIImage(named: pictureString) index = (index < myArray.count-1) ? index+1 : 0 } 涉及第三个表,当您构建DQL(学说查询)原则时,通常称为此类关系中的联结表,这取决于您定义的关系的性质作为注释,所以考虑你的查询

ManyToMany

您要加入$teamsingroup = $em->getRepository("AppBundle\Model\Entity\Team") ->createQueryBuilder('o') ->innerJoin('o.group', 't') 实体,Team部分Group部分innerJoin('o.group')是团队实体的别名,oo.group中定义的属性1}}名为Team的实体。

group

为此类型的关系doctrine定义了/** * @ORM\ManyToMany(targetEntity="Groups", mappedBy="team") */ protected $group; 注释,首先将您的团队表连接到联结表,然后将您的联结表与groups表连接,结果SQL将类似于

ManyToMany

另一个与您为每个小组建立团队相关的方法是,您可以通过在圈内排除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 部分来最小化您的代码,一旦您将团队属性定义为createQueryBuilder,即每个ArrayCollection通过调用组对象上的$this->team = new ArrayCollection();函数,您将获得与该特定组关联的团队集合,类似于以下代码。

getTeam()

答案 1 :(得分:0)

我猜它是使用INNER JOIN的字面选择语句,使用键列将实体类定义为mappedBy或inversedBy。 为什么不看一下学说日志并看看本机sql是由什么组成的?

How to get Doctrine to log queries in Symfony2(stackoverflow)

http://vvv.tobiassjosten.net/symfony/logging-doctrine-queries-in-symfony2/(一些代码示例)

我不知道你背后的用户故事,但我也听说建议使用一对多关系而不是多对多关系,除非有充分的理由这样做,因为大多数情况下可以通过重新考虑模型来处理一对多。