2016-01-19 45 views
6

我最近解決了一個查詢ManyToMany關係連接表的問題,解決方案與此answer相同,並且想知道它是如何工作的。 可以說我有groupsteam之間的簡單ManyToMany關係,將有會自動在這裏內連接如何使用Doctrine和Symfony2在多對多關係上工作

組實體

/** 
* 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表要獲得一個組中的所有團隊,我將不得不查詢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有沒有更好的方法。

回答

5

在兩個實體之間使用ManyToMany涉及第三個表,通常在您構建DQL(原則查詢)原則時根據您定義爲註釋的關係的性質自動連接結點表時通常稱爲此類關係中的聯結表考慮到您的查詢

$teamsingroup = $em->getRepository("AppBundle\Model\Entity\Team") 
        ->createQueryBuilder('o') 
        ->innerJoin('o.group', 't') 

您在innerJoin('o.group')部分oGroup實體加盟Team實體是團隊實體別名和o.group指命名爲groupTeam實體定義的屬性。

/** 
* @ORM\ManyToMany(targetEntity="Groups", mappedBy="team") 
*/ 
protected $group; 

這對於這種類型的關係學說的定義的ManyToMany註釋第一次加入您的團隊表接線表,然後加入你結表組表中,將所得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 

另一件事與你爲每個團隊獲得團隊的方式有關,一旦你將團隊屬性定義爲ArrayCollection i,你可以通過在循環中排除createQueryBuilder部分來最小化你的代碼。在每個組對象上通過調用getTeam()函數來獲得與該特定組相關聯的團隊集合,類似於下面的代碼。

foreach ($groups as $group) { 
    $teamsingroup = $group->getTeam(); 
    echo "</b>".$group->getGroupname()."</b></br>"; 
    foreach ($teamsingroup as $teamingroup) { 
     echo $teamingroup->getTeam()."</br>"; 
    } 
} 
+1

謝謝你,這減少了我的代碼,它開始了我思考更精簡的代碼的方式。這100%回答了我的問題。 SO是一個很棒的平臺。 +1 –

0

我想這實際上是使用INNER JOIN使用鍵列定義的實體類作爲mappedBy或inversedBy選擇語句。 爲什麼你不看看doctrine日誌,看看原生sql是由什麼組成的?

How to get Doctrine to log queries in Symfony2(計算器)

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

我不知道這背後用戶的故事,但我也聽說,這是推薦使用一對多的關係,而不是多個除非有充分的理由這麼做,因爲大多數情況下可以通過重新考慮模型來一對多地處理。

+0

嗨,謝謝你的回答,是的,我確實考慮過'OneToMany' - 'ManyToOne'代替'ManyToMany'。但是,一個很大的但它保守的不一樣,你有一個'OneToMany - ManyToOne'這一方,這意味着我們必須使用循環來插入記錄,這不僅是凌亂的,而且還涉及到很多自定義代碼(提示:它涉及使用'clone'或'detach()'_shivers!_)來執行簡單的CRUD操作。因此也是很好的「ManyToMany」。 –

相關問題