「友人」の関係の要件に応じて、この問題を解決するにはいくつかの方法があります。
単方向
単純なアプローチは、一方向の多対多の関連付けを使用することで、それがどこ双方向1(同期の両側を保つ)かのように扱うでしょう:
/**
* @Entity
*/
class User
{
/**
* @Id
* @Column(type="integer")
*/
private $id;
/**
* @ManyToMany(targetEntity="User")
* @JoinTable(name="friends",
* joinColumns={@JoinColumn(name="user_a_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="user_b_id", referencedColumnName="id")}
*)
* @var \Doctrine\Common\Collections\ArrayCollection
*/
private $friends;
/**
* Constructor.
*/
public function __construct()
{
$this->friends = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* @return array
*/
public function getFriends()
{
return $this->friends->toArray();
}
/**
* @param User $user
* @return void
*/
public function addFriend(User $user)
{
if (!$this->friends->contains($user)) {
$this->friends->add($user);
$user->addFriend($this);
}
}
/**
* @param User $user
* @return void
*/
public function removeFriend(User $user)
{
if ($this->friends->contains($user)) {
$this->friends->removeElement($user);
$user->removeFriend($this);
}
}
// ...
}
ます$userA->addFriend($userB)
、$userB
とお友達のコレクションには$userA
、$userA
は$userB
のフレンズコレクションに追加されます。
また、「友人」テーブル(1,2および2,1)に2つのレコードが追加されます。これは重複したデータと見なすことができますが、コードを大幅に簡略化します。たとえば、あなたが$userA
のすべての友人を見つける必要があるとき、あなたは、単に行うことができます。
SELECT u FROM User u JOIN u.friends f WHERE f.id = :userId
あなたが双方向関連と同じように2つの異なるプロパティをチェックする必要はありません。双方向の関連付けを使用する場合
双方向
User
エンティティは、例えば2つの特性、$myFriends
と$friendsWithMe
を有するであろう。上記と同じ方法でそれらを同期させることができます。
主な違いは、データベースレベルでは、関係(1,2または2,1)を表すレコードが1つしかないことです。これにより、両方のプロパティをチェックする必要があるため、「すべての友だちを探す」クエリが少し複雑になります。
もちろん、addFriend()
が$myFriends
と$friendsWithMe
の両方を更新して(そして反対側を同期させて)確実にすることで、データベースに2つのレコードを使用することができます。エンティティの複雑さが増しますが、クエリは少し複雑になります。
OneToMany/ManyToOne
ユーザーが友人を追加できるシステムが必要ですが、その友人は、彼らが実際に友達であることを確認する必要がある場合、あなたはjoin-はでその確認を保存する必要があります表。ManyToManyの関連付けはなくなりましたが、User
< - OneToMany - >Friendship
< - ManyToOne - >User
のようなものはもうありません。
あなたはこのテーマに関する私のブログの記事を読むことができます:
単方向は=>プロパティ 'のためのアクセスの種類を判別できませんでした...' – Trix
あなたがする必要があります'id'プロパティをマップします。私は例にそれを追加しました(整数としてマップされていますが、あなたが好きかもしれません)。 –
非常に便利な答えです。私にとって、追加する重要な部分は '$ user-> addFriend($ this);'でした。 – StockBreak