114

ZendFramework2とDoctrine2を使用してアプリケーションを開発しています。

アノテーションを書いていると、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;

簡単に検索して次のことを見つけましたが、まだ混乱しています。

4

4 に答える 4

168
  • マップされたByは、(双方向)関連付けの逆側で指定する必要があります
  • reversedByは、(双方向)アソシエーションの所有側で指定する必要があります

教義の文書から:

  • ManyToOneは、常に双方向アソシエーションの所有側です。
  • OneToManyは、常に双方向アソシエーションの逆です。
  • OneToOneアソシエーションの所有側は、外部キーを含むテーブルを持つエンティティです。

https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.htmlを参照してください

于 2012-09-19T13:32:37.033 に答える
71

上記の答えは私が何が起こっているのかを理解するのに十分ではなかったので、それをさらに掘り下げた後、私が理解したように苦労した人々にとって意味のある説明の方法があると思います。

reversedByとmappedByは、必要な情報を取得するために実行する必要のあるSQLクエリの数を減らすためにINTERNALDOCTRINEエンジンによって使用されます。reversedByまたはmappedByを追加しないかどうかを明確にするために、コードは引き続き機能しますが、最適化されません。

たとえば、以下のクラスを見てください。

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エンジンはその上の参照(mappedByカテゴリ)を使用できるということです。さて...ここで私がそうであったように混乱しないでください...カテゴリはクラス名を参照していません。それは「保護された$category」と呼ばれるタスククラスのプロパティを参照しています。

同様に、Tasksクラスでは、プロパティ$categoryがinversedBy = "tasks"であると述べています。これは複数形であることに注意してください。これはクラス名の複数形ではありませんが、プロパティがカテゴリで「保護された$tasks」と呼ばれているからです。クラス。

これを理解すると、inversedByとmappedByが何をしているのか、そしてこの状況でそれらをどのように使用するのかを非常に簡単に理解できるようになります。

私の例で「tasks」のような外部キーを参照している側は、常にinversedBy属性を取得します。これは、そのクラスのどのクラス(targetEntityコマンドを介して)とどの変数(inversedBy =)が「逆方向に機能する」かを知る必要があるためです。話し、からカテゴリ情報を取得します。これを覚える簡単な方法は、foreignkey_idを持つクラスがinversedByを持つ必要があるクラスです。

カテゴリと同様に、その$ tasksプロパティ(テーブルにはありませんが、最適化のためにクラスの一部のみを覚えておいてください)がMappedBy'tasks'であるのに対し、これにより2つのエンティティ間に正式な関係が作成され、Doctrineが安全に使用できるようになります。 2つの別個のSELECTステートメントの代わりに、JOINSQLステートメントを使用してください。マップされたByがないと、ドクトリンエンジンはJOINステートメントから、カテゴリ情報を配置するためにクラス「タスク」にどの変数を作成するかを認識しません。

これがそれをもう少しよく説明することを願っています。

于 2016-01-04T00:48:02.590 に答える
22

双方向の関係では、所有側と逆側の両方があります

マップされたBy:双方向関係の逆側に入れられますそれ自身の側を参照するには

reversedBy:双方向関係の所有側に入れますその逆側を参照するには

OneToOne、OneToMany、またはManyToManyマッピング宣言で使用されるmappedBy属性。

OneToOne、ManyToOne、またはManyToManyマッピング宣言で使用されるinversedBy属性

注意:双方向関係の所有側は、外部キーを含む側です。

DoctrineドキュメントへのinversedByとmappedByに関する2つのリファレンスがあります: First LinkSecond Link

于 2013-11-20T16:12:38.477 に答える
2

5.9.1。所有と逆の側面

多対多の関連付けの場合、所有しているエンティティとその逆のエンティティを選択できます。開発者の観点から、どちらの側が所有側に適しているかを決定するための非常に単純なセマンティックルールがあります。接続管理を担当しているエンティティを自問し、それを所有側として選択するだけです。

ArticleとTagの2つのエンティティの例を見てください。アーティクルをタグに接続したい場合、またはその逆の場合は常に、この関係に責任があるのはアーティクルです。新しい記事を追加するときはいつでも、既存または新しいタグと接続する必要があります。記事の作成フォームはおそらくこの概念をサポートし、タグを直接指定できるようになります。これが、コードをより理解しやすくするために、記事を所有側として選択する必要がある理由です。

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html

于 2016-09-25T08:20:38.173 に答える