Как внутреннее соединение работает с отношениями «многие ко многим» с помощью Doctrine и Symfony2

Недавно я разработал проблему с запросом ManyToMany соединений отношений ManyToMany , решение было таким же, как и этот ответ, и ManyToMany вопросом, как это работает. скажем, у меня есть простые отношения ManyToMany между groups и team , будут groups_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 group_team.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.

Solutions Collecting From Web of "Как внутреннее соединение работает с отношениями «многие ко многим» с помощью Doctrine и Symfony2"

Использование ManyToMany между двумя объектами включает в себя третью таблицу, обычно называемую таблицей переходов в этом типе отношения, когда вы создаете доктрину DQL (доктрина), которая автоматически присоединяется к таблице соединений в зависимости от характера отношения, которое вы определили как аннотацию, поэтому учитывая ваш запрос

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

Вы присоединяетесь к объекту Group объектом Group in innerJoin('o.group') часть o является псевдонимом для объекта Team, а o.group относится к свойству, определенному в o.group Team названном как group .

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

Еще одна вещь, связанная с вашим способом получения команды для каждой группы, вы можете свести к минимуму свой код, исключив часть 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>"; } } 

Я предполагаю, что это буквально выбирает оператор с INNER JOIN, используя ключевые столбцы, определенные классом сущности как mappedBy или inversedBy. Почему бы вам не взглянуть на журнал доктрины и посмотреть, что скомпилирован родной sql?

Как заставить Doctrine регистрировать запросы в Symfony2 (stackoverflow)

http://vvv.tobiassjosten.net/symfony/logging-doctrine-queries-in-symfony2/ (некоторые примеры кода)

Я не знаю вашей истории пользователя за этим, но я также слышал, что рекомендуется использовать отношения от одного до многих, а не многие для многих, если нет веских оснований для этого, так как большинство случаев могут обрабатываться одним для многих путем пересмотра моделей.