Diğer one-to-one veya one-to-many ilişkilerin aksine, ManyToMany ilişkilerde cascade={"remove"} veya orphanRemoval=true kullanmanıza gerek yoktur, o nedenle bu yazımız sadece ManyToMany ilişkileri nasıl kullanmanız gerektiğini gösterecek. Bidirectional ilişki kullanmamızın nedeni, her iki entity üzerinden her iki tarafa doğru gidebilme olanağımızın olmasıdır. Örneğimizin teması futbol olacak.


Ön bilgi


Eğer herhangi bir Team veya Tournament kaydını silerseniz, silinen kayıtla ilişkili olan tüm kayıtlar, veritabanındaki team_tournament bağlantı tablosundan otomatik olarak silineceklerdir. Bu tablo doctrine tarafından otomatik olarak yaratıldığı için, sizin yapmanız gereken birşey yoktur.


Dizayn




class Team
{
/**
* @ORM\ManyToMany(targetEntity="Tournament", mappedBy="teams")
*/
private $tournaments;

public function __construct()
{
$this->tournaments = new ArrayCollection();
}

public function addTournament(Tournament $tournament)
{
if (!$this->tournaments->contains($tournament)) {
$this->tournaments[] = $tournament;
$tournament->addTeam($this);
}

return $this;
}

public function removeTournament(Tournament $tournament)
{
if ($this->tournaments->contains($tournament)) {
$this->tournaments->removeElement($tournament);
$tournament->removeTeam($this);
}
}
}

class Tournament
{
/**
* @ORM\ManyToMany(targetEntity="Team", inversedBy="tournaments")
* @ORM\JoinTable(
* name="team_tournament",
* joinColumns={
* @ORM\JoinColumn(name="tournament_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="team_id", referencedColumnName="id")
* }
* )
*/
private $teams;

public function __construct()
{
$this->teams = new ArrayCollection();
}

public function addTeam(Team $team)
{
if (!$this->teams->contains($team)) {
$this->teams[] = $team;
$team->addTournament($this);
}

return $this;
}

public function removeTeam(Team $team)
{
if ($this->teams->contains($team)) {
$this->teams->removeElement($team);
$team->removeTournament($this);
}
}
}

`team` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
)

`tournament` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
)

`team_tournament` (
`tournament_id` int(11) NOT NULL,
`team_id` int(11) NOT NULL,
PRIMARY KEY (`tournament_id`,`team_id`),
KEY `IDX_8386CA1C33D1A3E7` (`tournament_id`),
KEY `IDX_8386CA1C296CD8AE` (`team_id`),
CONSTRAINT `FK_8386CA1C296CD8AE` FOREIGN KEY (`team_id`) REFERENCES `team` (`id`),
CONSTRAINT `FK_8386CA1C33D1A3E7` FOREIGN KEY (`tournament_id`) REFERENCES `tournament` (`id`)
)

mysql> SELECT
-> team.id AS TaamId,
-> team.name AS TeamName,
-> tournament.id AS TournamentId,
-> tournament.name AS TournamentName
-> FROM team
-> INNER JOIN team_tournament ON team.id = team_tournament.team_id
-> INNER JOIN tournament ON team_tournament.tournament_id = tournament.id;
+--------+-------------------+--------------+-----------------------+
| TaamId | TeamName | TournamentId | TournamentName |
+--------+-------------------+--------------+-----------------------+
| 1 | Fenerbahce | 1 | UEFA Champions League |
| 4 | Arsenal | 1 | UEFA Champions League |
| 7 | Bayern Munich | 1 | UEFA Champions League |
| 2 | Galatasaray | 2 | UEFA Europa League |
| 5 | Liverpool | 2 | UEFA Europa League |
| 8 | Borussia Dortmund | 2 | UEFA Europa League |
| 3 | Besiktas | 3 | UEFA Super Cup |
| 6 | Manchester United | 3 | UEFA Super Cup |
| 9 | Werder Bremen | 3 | UEFA Super Cup |
+--------+-------------------+--------------+-----------------------+

Yukarıda da gördüğümüz gibi, ManyToMany ilişki veritabanında otomatik olarak team_tournament bağlantı tablosunu yaratıyor. Bu tablo doctrine tarafından otomatik olarak yaratıldığı için, bizim yapmamız gereken birşey yoktur. Uzun örnek için bu örneği inceleyebilirsiniz.


Testler


Team silme: Team ve Team ile ilgili tüm kayıtlar team_tournament tablosundan silinir.


$this->entityManager->remove($entity);
$this->entityManager->flush();

doctrine.DEBUG: SELECT ... FROM team WHERE id = ? LIMIT 1 ["1"] []
doctrine.DEBUG: "START TRANSACTION" [] []
doctrine.DEBUG: DELETE FROM team_tournament WHERE team_id = ? [1] []
doctrine.DEBUG: DELETE FROM team WHERE id = ? [1] []
doctrine.DEBUG: "COMMIT" [] []

Tournament silme: Tournament ve Tournament ile ilgili tüm kayıtlar team_tournament tablosundan silinir.


$this->entityManager->remove($entity);
$this->entityManager->flush();

doctrine.DEBUG: SELECT ... FROM tournament WHERE id = ? LIMIT 1 ["1"] []
doctrine.DEBUG: "START TRANSACTION" [] []
doctrine.DEBUG: DELETE FROM team_tournament WHERE tournament_id = ? [1] []
doctrine.DEBUG: DELETE FROM tournament WHERE id = ? [1] []
doctrine.DEBUG: "COMMIT" [] []

Okunacak notlar