Doctrine Relation
One to One
概要
- 1対1
- 例:ユーザテーブルのレコードはプロフィールテーブルのレコードを一つのみ紐付けられる
以下コマンドでOne to One関係を作成
symfony console make:entity
既存のEntity名を入力(ex. userProfile)
関係カラムの名称を入力(ex. user)
関係を入力(ex. OneToOne)
紐づけ対象のEntity(ex. User)
nullableにするか(ex. no)
双方向にしたいかどうか(ex. yes)
関係の相手側の名称をどうするか(ex. userProfile)
example_userProfile.php
#[ORM\OneToOne(inversedBy: 'userProfile', cascade: ['persist', 'remove'])]
#[ORM\JoinColumn(nullable: false)]
private ?User $user = null;
// ...
public function getUser(): ?User
{
return $this->user;
}
public function setUser(User $user): self
{
$this->user = $user;
return $this;
}
example_user.php
#[ORM\OneToOne(mappedBy: 'user', cascade: ['persist', 'remove'])]
private ?UserProfile $userProfile = null;
// ...
public function getUserProfile(): ?UserProfile
{
return $this->userProfile;
}
public function setUserProfile(UserProfile $userProfile): self
{
// set the owning side of the relation if necessary
if ($userProfile->getUser() !== $this) {
$userProfile->setUser($this);
}
$this->userProfile = $userProfile;
return $this;
}
mappedBy: フィールド名
targetEntity: 関係を持つEntity
Cascade: Userを作成した場合,自動でUserProfileが作成される,"remove"がある場合削除も自動的
ionversedBy: mappedByと逆のフィールド名
JoinColumn: 関係を持っているEntity(こちらがあるEntityには共通Columnは無い)
One to Many
- 1対多
- 例:投稿テーブルのレコードはコメントテーブルのレコードを複数紐付けられる
OneToOneとほぼ同様に作成可能
symfony console make:MicroPost
... > OneToMany
Comment.php
#[ORM\ManyToOne(inversedBy: 'comment')]
#[ORM\JoinColumn(nullable: false)]
private ?MicroPost $post = null;
// ...
public function getPost(): ?MicroPost
{
return $this->post;
}
public function setPost(?MicroPost $post): self
{
$this->post = $post;
return $this;
}
MicroPost.php
#[ORM\OneToMany(mappedBy: 'post', targetEntity: Comment::class, orphanRemoval: true)]
private Collection $comment;
// ...
/**
* @return Collection<int, Comment>
*/
public function getComment(): Collection
{
return $this->comment;
}
public function addComment(Comment $comment): self
{
if (!$this->comment->contains($comment)) {
$this->comment->add($comment);
$comment->setPost($this);
}
return $this;
}
public function removeComment(Comment $comment): self
{
if ($this->comment->removeElement($comment)) {
// set the owning side to null (unless already changed)
if ($comment->getPost() === $this) {
$comment->setPost(null);
}
}
return $this;
}
Collectionで扱える
- Collection: https://gotohayato.com/content/89/
Repositoryで変更や関係などを保存する場合
- 属している側のRepositoryを利用する MicroPostRepository
Many to Many
- 多対多
- 例:フォロー機能で,ユーザテーブルのレコードは複数のユーザテーブルのレコードをフォローできる
- フォローされているユーザテーブルのレコードも同様
同様に作成可能
- Userは複数のMicroPostにいいね可能
User.php
#[ORM\ManyToMany(targetEntity: MicroPost::class, mappedBy: 'likedBy')]
private Collection $liked;
// ...
/**
* @return Collection<int, MicroPost>
*/
public function getLiked(): Collection
{
return $this->liked;
}
public function addLiked(MicroPost $liked): self
{
if (!$this->liked->contains($liked)) {
$this->liked->add($liked);
$liked->addLikedBy($this);
}
return $this;
}
public function removeLiked(MicroPost $liked): self
{
if ($this->liked->removeElement($liked)) {
$liked->removeLikedBy($this);
}
return $this;
}
MicroPost.php
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'liked')]
private Collection $likedBy;
// ...
/**
* @return Collection<int, User>
*/
public function getLikedBy(): Collection
{
return $this->likedBy;
}
public function addLikedBy(User $likedBy): self
{
if (!$this->likedBy->contains($likedBy)) {
$this->likedBy->add($likedBy);
}
return $this;
}
public function removeLikedBy(User $likedBy): self
{
$this->likedBy->removeElement($likedBy);
return $this;
}