Атрибут JoinTable
Атрибут JoinTable вешается на свойство сущности
и описывает промежуточную таблицу для связи
ManyToMany. Первым параметром передаётся имя
таблицы в базе данных. Внутри атрибута можно задать
колонки через joinColumns и
inverseJoinColumns, а также схему и индексы.
Синтаксис
#[JoinTable(name: table_name)]
Пример
Давайте создадим связь ManyToMany между
сущностями Article и Tag через
промежуточную таблицу 'article_tag':
<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
#[ORMEntity]
#[ORMTable(name: 'article')]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $title;
#[ORMManyToMany(targetEntity: Tag::class)]
#[ORMJoinTable(name: 'article_tag')]
private Collection $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getTags(): Collection
{
return $this->tags;
}
}
?>
Теперь опишем сущность Tag с обратной стороной связи:
<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
#[ORMEntity]
#[ORMTable(name: 'tag')]
class Tag
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $name;
#[ORMManyToMany(targetEntity: Article::class, mappedBy: 'tags')]
private Collection $articles;
public function __construct()
{
$this->articles = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getArticles(): Collection
{
return $this->articles;
}
}
?>
Результат выполнения команды создания схемы:
php bin/console doctrine:schema:update --force
"CREATE TABLE article_tag (article_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(article_id, tag_id))"
Пример
Давайте настроим колонки промежуточной таблицы через
joinColumns и inverseJoinColumns:
<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
#[ORMEntity]
#[ORMTable(name: 'article')]
class Article
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn(type: 'integer')]
private ?int $id = null;
#[ORMColumn(type: 'string', length: 255)]
private string $title;
#[ORMManyToMany(targetEntity: Tag::class)]
#[ORMJoinTable(
name: 'article_tag',
joinColumns: [
new ORMJoinColumn(
name: 'article_id',
referencedColumnName: 'id',
onDelete: 'CASCADE'
)
],
inverseJoinColumns: [
new ORMJoinColumn(
name: 'tag_id',
referencedColumnName: 'id',
onDelete: 'CASCADE'
)
]
)]
private Collection $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getTags(): Collection
{
return $this->tags;
}
}
?>
Результат выполнения команды создания схемы:
php bin/console doctrine:schema:update --force
"CREATE TABLE article_tag (article_id INT NOT NULL, tag_id INT NOT NULL, PRIMARY KEY(article_id, tag_id), FOREIGN KEY(article_id) REFERENCES article(id) ON DELETE CASCADE, FOREIGN KEY(tag_id) REFERENCES tag(id) ON DELETE CASCADE)"
Пример
Давайте сохраним статью с тегами и выведем количество связанных тегов:
<?php
namespace AppController;
use AppEntityArticle;
use AppEntityTag;
use DoctrineORMEntityManagerInterface;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article/create', name: 'article_create')]
public function create(EntityManagerInterface $em): Response
{
$article = new Article();
$article->setTitle('abcde');
$tag1 = new Tag();
$tag1->setName('article');
$tag2 = new Tag();
$tag2->setName('user');
$article->getTags()->add($tag1);
$article->getTags()->add($tag2);
$em->persist($article);
$em->persist($tag1);
$em->persist($tag2);
$em->flush();
return new Response((string) $article->getTags()->count());
}
}
?>
Результат выполнения кода:
"2"
Смотрите также
-
связь
ManyToMany,
для которой применяется промежуточная таблица -
атрибут
JoinColumn,
который задаёт колонку связи с сущностью -
атрибут
JoinColumns,
который объединяет несколько JoinColumn -
атрибут
InverseJoinColumn,
который задаёт обратную колонку связи