2012-09-19 7 views
78

ich meine Anwendung entwickle mit Zend Framework 2 und Lehre 2.Was ist der Unterschied zwischen inversedBy und mappedBy?

Während Anmerkungen writting, bin ich nicht in der Lage, den Unterschied zwischen mappedBy und inversedBy zu verstehen.

Wann sollte ich mappedBy verwenden?

Wann sollte ich inversedBy verwenden?

Wann sollte ich keines verwenden? Hier

ein Beispiel:

/** 
* 
* @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; 

Ich habe eine schnelle Suche und fand die folgenden, aber ich bin immer noch verwirrt:

Antwort

127
  • mappedBy hat auf der inversed Seite eines (bidirektional) angegeben werden Assoziation
  • inversedBy auf der besitzenden Seite festgelegt werden muss eines (bidirektional) association

aus Doktrin Dokumentation:

  • ManyToOn e ist immer die besitzende Seite einer bidirektionalen Assoziation.
  • OneToMany ist immer die inverse Seite einer bidirektionalen Assoziation.
  • Die Eigentümerseite einer OneToOne-Assoziation ist die Entität mit der Tabelle, die den Fremdschlüssel enthält.

Siehe http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html

+1

Seltsamer die Lehre documenter beschlossen, das yaml Beispiel für eine many-to-one bidirektionale Mapping auszulassen, wahrscheinlich das am häufigsten verwendete! –

+2

@PeterWooster, Best Practice ist Annotationen zu verwenden, da Sie alle Informationen über die Entität an einem Ort haben! –

+0

Dies gilt auch für viele zu viele Beziehungen. Für diejenigen: Sie können selbst die Eigentümerseite einer Viele-zu-Viele-Assoziation auswählen. – 11mb

20

In bidirektionale Beziehung hat sowohl eine besitzende Seite und eine inverse Seite

mappedBy: put in die inverse Seite einer bidirektionalen Beziehung zu seinem Besitz Seite zu verweisen

inversedBy: in die besitzende Seite einer bidirektionalen Beziehung einfügen Um auf seine inverse Seite

beziehen

UND

mappedBy Attribut mit der OneToOne, OneToMany oder ManyToMany Mapping Erklärung.

inversedBy Attribut, das mit der OneToOne-, ManyToOne- oder ManyToMany-Zuordnungsdeklaration verwendet wird.

Hinweis: Die besitzende Seite einer bidirektionalen Beziehung die Seite, die den Fremdschlüssel enthält.

zwei Referenz über inversedBy und mappedBy in Lehre Dokumentation: First Link, Second Link

+1

+1 für die Links mit einigen Beispielen. – Marcos

38

Die Antworten oben waren nicht ausreichend für mich zu verstehen, was los war, so nach dem in sie einzutauchen mehr ich glaube, ich habe einen Weg es zu erklären, dass es Sinn macht für Leute, die kämpfen mussten, wie ich es verstand.

inversedBy und mappedBy durch die INTERNE LEHRE verwendet werden Motor die Anzahl der SQL-Abfragen reduzieren es zu tun hat, die Informationen die Sie benötigen. Um klar zu sein, wenn Sie inversedBy oder mappedBy nicht hinzufügen, wird Ihr Code immer noch funktionieren, wird aber nicht optimiert sein.

So zum Beispiel, betrachten Sie die unten angegebenen Klassen:

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; 
} 

Diese Klassen, wenn Sie den Befehl auszuführen waren, das Schema zu generieren (zB bin/console doctrine:schema:update --force --dump-sql) Sie werden feststellen, dass die Kategorie Tabelle nicht eine Spalte für Aufgaben. (das ist, weil es keine Spaltenannotation darauf hat)

Die wichtige Sache, die hier zu verstehen ist, ist, dass die Variable Aufgaben nur dort ist, so kann die interne Doktrin-Engine die Referenz darüber verwenden, die ihre mappedBy-Kategorie angibt. Nun ... sei hier nicht verwirrt wie ich war ... Kategorie bezieht sich NICHT auf die Klasse NAME, es bezieht sich auf die Eigenschaft auf der Task-Klasse namens 'protected $ category'.

Wie weise, auf die Klasse Aufgaben der Eigenschaft $ Kategorie es erwähnt ist inversedBy = „Aufgaben“, bemerken diese Plural ist, dies nicht der PLURAL des Klassennamens ist, aber nur, weil die Eigenschaft genannt ‚geschützt $ tasks 'in der Category-Klasse.

Sobald Sie dies verstehen, wird es sehr einfach zu verstehen, was inversedBy und mappedBy tun und wie Sie sie in dieser Situation verwenden. Die Seite, die den Fremdschlüssel wie "Aufgaben" in meinem Beispiel referenziert, erhält immer das Attribut inversedBy, weil sie wissen muss, welche Klasse (über den targetEntity-Befehl) und welche Variable (inversedBy =) für diese Klasse "funktioniert" rückwärts 'sozusagen und holen Sie sich die Kategorie Informationen aus. Eine einfache Möglichkeit, sich daran zu erinnern, ist die Klasse, die die Fremdschlüssel-ID haben müsste, die inversedBy haben muss.

Wo wie mit Kategorie, und seine $ tasks -Eigenschaft (die nicht auf der Tabelle zu erinnern, nur ein Teil der Klasse für Optimierungszwecke) ist MappedBy "Aufgaben", erstellt dies die Beziehung offiziell zwischen den beiden Entitäten so doctrine kann jetzt JOIN SQL-Anweisungen anstelle von zwei separaten SELECT-Anweisungen verwenden. Ohne mappedBy würde die Doktrin-Engine aus der JOIN-Anweisung nicht wissen, welche Variable in der Klasse 'Task' erstellt wird, um die Kategorieinformationen zu setzen.

Hoffe das erklärt es ein bisschen besser.

+4

Das ist sehr gut erklärt und danke für Ihre Mühe. Ich kam von Laravel Eloquent zur Doktrin und es war schwer für mich, die Logik hier zu verstehen. Gut gemacht. 'Kategorie bezieht sich NICHT auf die Klasse NAME, es bezieht sich auf die Eigenschaft in der Task-Klasse 'geschützte Kategorie' genannt alles, was ich brauchte. Es hat nicht nur mein Problem gelöst, es hat mir auch geholfen zu verstehen. Die beste Antwort IMO :-) –

+0

Danke, nahm mich eine Weile, um dies herauszufinden. Froh, dass es geholfen hat :). –

+0

Ich kam auch von Eloquent, das hat mir sehr geholfen. Mein einziger Fehlerpunkt ist jetzt, wie man den Setter/Getter dafür setzt, ich lerne immer noch die Seile davon. – Eman

1

5.9.1. Besitz und umgekehrte Seite

Für viele-zu-viele Verknüpfungen können Sie auswählen, welche Entität Eigentümer und welche die inverse Seite ist. Es gibt eine sehr einfache semantische Regel, um zu entscheiden, welche Seite aus Entwicklerperspektive besser geeignet ist, die besitzende Seite zu sein. Sie müssen sich nur fragen, welche Instanz für das Verbindungsmanagement zuständig ist und diese als Eigentümerseite auswählen.

Nehmen Sie ein Beispiel für zwei Entitäten Artikel und Tag. Wann immer Sie einen Artikel mit einem Tag verbinden möchten und umgekehrt, ist meistens der Artikel für diese Beziehung verantwortlich. Wenn Sie einen neuen Artikel hinzufügen, möchten Sie ihn mit vorhandenen oder neuen Tags verbinden. Ihr Artikelformular erstellen wird wahrscheinlich diesen Begriff unterstützen und erlauben, die Tags direkt anzugeben. Aus diesem Grund sollten Sie den Artikel als Besitz Seite holen, wie es der Code verständlicher macht:

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

Verwandte Themen