Zend Framework 2とDoctrine 2.を使用してアプリケーションを開発しています。
注釈を書いている間、mappedBy
とinversedBy
の違いを理解できません。
いつmappedBy
を使用すべきですか?
いつinversedBy
を使用すべきですか?
どちらを使用しないのですか?
以下に例を示します。
/**
*
* @ORM\OneToOne(targetEntity="\custMod\Entity\Person", mappedBy="customer")
* @ORM\JoinColumn(name="personID", referencedColumnName="id")
*/
protected $person;
/**
*
* @ORM\OneToOne(targetEntity="\Auth\Entity\User")
* @ORM\JoinColumn(name="userID", referencedColumnName="id")
*/
protected $user;
/**
*
* @ORM\ManyToOne (targetEntity="\custMod\Entity\Company", inversedBy="customer")
* @ORM\JoinColumn (name="companyID", referencedColumnName="id")
*/
protected $company;
クイック検索を行ったところ、次のことがわかりましたが、まだ混乱しています。
from doctrine documentation:
上記の答えは何が起こっているのかを理解するのに十分ではなかったので、それをさらに掘り下げた後、私は理解するのに苦労した人々にとって意味のあるそれを説明する方法があると思います。
inversedByとmappedByは、INTERNAL DOCTRINEエンジンからSQLクエリの数を減らすで必要な情報を取得するために使用されます。 inversedByまたはmappedByを追加しない場合に明確にするために、コードは引き続き機能しますが、optimizedにはなりません。
たとえば、以下のクラスを見てください。
class Task
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="task", type="string", length=255)
*/
private $task;
/**
* @var \DateTime
*
* @ORM\Column(name="dueDate", type="datetime")
*/
private $dueDate;
/**
* @ORM\ManyToOne(targetEntity="Category", inversedBy="tasks", cascade={"persist"})
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
}
class Category
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="Task", mappedBy="category")
*/
protected $tasks;
}
これらのクラスは、コマンドを実行してスキーマを生成する場合(たとえば、bin/console doctrine:schema:update --force --dump-sql
)Categoryテーブルには、タスクの列がありません。 (これは列注釈がないためです)
ここで理解する重要なことは、変数タスクがそこにあるだけなので、内部doctrine=エンジンはその上のByByカテゴリを示す参照を使用できることです。ここで混乱しないでください。 カテゴリはクラス名を参照していません、 'protected $ category'と呼ばれるTaskクラスのプロパティを参照しています。
同様に、Tasksクラスでは、プロパティ$ categoryは、inversedBy = "tasks"であると言及しています。これは複数形であることに注意してくださいこれはクラス名の複数ではありません Categoryクラスの保護された$ tasks。
これを理解すると、inversedByとmappedByの動作と、この状況でそれらを使用する方法を非常に簡単に理解できるようになります。
私の例で「タスク」のような外部キーを参照している側は、「targetEntityコマンドを介して」そのクラスのどのクラス(「逆方向に動作する」)の変数(inversedBy =)を知る必要があるため、常にinversedBy属性を取得します話し、カテゴリ情報を取得します。これを覚える簡単な方法は、foreignkey_idを持つクラスが、inversedByを持つ必要があるクラスです。
カテゴリと同様に、その$ tasksプロパティ(テーブルにはない、最適化のためにクラスの一部のみ)がMappedBy 'tasks'である場合、これにより2つのエンティティ間の関係が公式に作成され、doctrineは2つの個別のSELECTステートメントの代わりにJOIN SQLステートメントを安全に使用できるようになりました。mappedByがなければ、doctrineエンジンはJOINステートメントからクラスの変数を作成することを知りませんカテゴリ情報を入力する「タスク」。
これでもう少し良くなることを願っています。
5.9.1。所有側と逆側
多対多の関連付けの場合、所有するエンティティとその反対側を選択できます。開発者の観点から、どちらの側が所有側に適しているかを決定する非常に単純なセマンティックルールがあります。接続管理を担当するのはどのエンティティかを自問するだけでよく、それを所有側として選択します。
ArticleとTagの2つのエンティティの例を見てみましょう。アーティクルをタグに接続したい場合、またはその逆の場合、この関係を担当するのは主にアーティクルです。新しい記事を追加するたびに、既存のタグまたは新しいタグに接続します。記事の作成フォームはおそらくこの概念をサポートし、タグを直接指定できます。このため、コードをより理解しやすくするため、Articleを所有側として選択する必要があります。
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html