最近、ManyToMany
関係結合テーブルのクエリに関する問題を解決しました。解決策はこれと同じでした answer で、どのように機能するのか疑問に思いました。 ManyToMany
と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
テーブルをクエリする必要があります。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と教義でこれを行うためのより良い方法はありますか?.
2つのエンティティ間でManyToMany
を使用すると、DQL(doctrineクエリ)を構築するときに、このタイプのリレーションで一般にジャンクションテーブルと呼ばれる3番目のテーブルが必要になりますdoctrineは、に応じてジャンクションテーブルを自動的に結合しますアノテーションとして定義した関係の性質なので、クエリを検討します
_$teamsingroup = $em->getRepository("AppBundle\Model\Entity\Team")
->createQueryBuilder('o')
->innerJoin('o.group', 't')
_
innerJoin('o.group')
パートでTeam
エンティティをGroup
エンティティと結合しています。o
はチームエンティティのエイリアスであり、_o.group
_はで定義されたプロパティを参照します。 Team
という名前のgroup
エンティティ。
_/**
* @ORM\ManyToMany(targetEntity="Groups", mappedBy="team")
*/
protected $group;
_
このタイプの関係に対してManyToMany
アノテーションが定義されているdoctrine最初にチームテーブルをジャンクションテーブルと結合し、次にジャンクションテーブルをグループテーブルと結合すると、結果の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
_
各グループのチームを取得する方法に関連するもう1つのことは、チームプロパティをcreateQueryBuilder
、つまり$this->team = new ArrayCollection();
onとして定義したら、ループ内のArrayCollection
部分を除外することでコードを最小限に抑えることができます。各グループオブジェクトは、以下のコードのようにグループオブジェクトでgetTeam()
関数を呼び出すことにより、その特定のグループに関連付けられたチームのコレクションを取得します。
_foreach ($groups as $group) {
$teamsingroup = $group->getTeam();
echo "</b>".$group->getGroupname()."</b></br>";
foreach ($teamsingroup as $teamingroup) {
echo $teamingroup->getTeam()."</br>";
}
}
_
エンティティクラスをmappedByまたはinversedByとして定義されたキー列を使用して、文字通りINNERJOINを使用したselectステートメントだと思います。 doctrine logを見て、ネイティブSQLが何で構成されているかを確認してみませんか?
Symfony2でクエリをログに記録するためのDoctrineの取得方法 (stackoverflow)
http://vvv.tobiassjosten.net/symfony/logging-doctrine-queries-in-symfony2/ (いくつかのコード例)
この背後にあるユーザーストーリーはわかりませんが、ほとんどの場合は1人で処理できるため、強い理由がない限り、多対多ではなく1対多の関係を使用することをお勧めします。モデルを再考することによって多くの人に。