Tworzę swoją aplikację przy użyciu Zend Framework 2 i Doctrine 2.
Pisząc adnotacje, nie jestem w stanie zrozumieć różnicy między mappedBy
i inversedBy
.
Kiedy stosować mappedBy
?
Kiedy stosować inversedBy
?
Kiedy nie należy ich używać?
Oto przykład:
/**
*
* @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;
Zrobiłem szybkie wyszukiwanie i znalazłem następujące, ale nadal jestem zdezorientowany:
php
doctrine-orm
Deweloper
źródło
źródło
Powyższe odpowiedzi nie były dla mnie wystarczające, abym zrozumiał, co się dzieje, więc po dokładniejszym zagłębieniu się w to myślę, że mam sposób, aby to wyjaśnić, który będzie miał sens dla ludzi, którzy zmagali się ze zrozumieniem tak, jak ja.
inversedBy i mappedBy są używane przez silnik INTERNAL DOCTRINE w celu zmniejszenia liczby zapytań SQL, które musi wykonać, aby uzyskać potrzebne informacje. Dla jasności, jeśli nie dodasz inversedBy lub mappedBy, twój kod będzie nadal działał, ale nie zostanie zoptymalizowany .
Na przykład spójrz na poniższe klasy:
Te klasy, jeśli uruchomisz polecenie do wygenerowania schematu (na przykład
bin/console doctrine:schema:update --force --dump-sql
), zauważysz, że tabela Kategoria nie zawiera kolumny dla zadań. (dzieje się tak, ponieważ nie ma na sobie adnotacji w kolumnie)Ważną rzeczą do zrozumienia jest to, że zmienne zadania są dostępne tylko po to, aby wewnętrzny silnik doktryny mógł użyć odniesienia powyżej niego, które mówi, że jego kategoria mappedBy. Teraz ... nie daj się zmylić, tak jak ja ... Kategoria NIE odnosi się do NAZWY KLASY , ale odnosi się do właściwości klasy Task o nazwie „protected $ category”.
Podobnie jak mądrze, w klasie Tasks właściwość $ category wspomina, że jest inversedBy = "zadania", zauważ, że jest to liczba mnoga, NIE JEST TO LICZBA LICZBOWA NAZWY KLASY , ale tylko dlatego, że właściwość ta nosi nazwę "chronione $ zadania" w kategorii klasa.
Kiedy już to zrozumiesz, bardzo łatwo będzie zrozumieć, co robią inversedBy i mappedBy oraz jak ich używać w tej sytuacji.
Strona, która odwołuje się do klucza obcego, taka jak `` task '' w moim przykładzie, zawsze otrzymuje atrybut inversedBy, ponieważ musi wiedzieć, która klasa (za pomocą polecenia targetEntity) i jaka zmienna (inversedBy =) tej klasy ma `` działać wstecz '', aby mówić i uzyskać informacje o kategorii. Łatwym sposobem na zapamiętanie tego jest to, że klasa, która miałaby klucz obcy_id, jest tą, która musi mieć parametr inversedBy.
Tam, gdzie tak jak w przypadku category, a jej właściwość $ task (której nie ma w tabeli pamiętajcie, tylko część klasy do celów optymalizacji) to MappedBy 'task', tworzy to oficjalnie relację między dwoma bytami, tak aby doktryna mogła teraz bezpiecznie użyj instrukcji JOIN SQL zamiast dwóch oddzielnych instrukcji SELECT. Bez mappedBy silnik doktryny nie wiedziałby z instrukcji JOIN, że utworzy zmienną w klasie „Zadanie”, aby umieścić informacje o kategorii.
Mam nadzieję, że to wyjaśnia to trochę lepiej.
źródło
Category is NOT referring TO THE CLASS NAME, its referring to the property on the Task class called 'protected $category'
wszystko, czego potrzebowałem. To nie tylko rozwiązało mój problem, ale pomogło mi to zrozumieć. Najlepsza odpowiedź IMO :-)W relacji dwukierunkowej ma zarówno stronę właścicielską, jak i odwrotną
mappedBy : put into Odwrotna strona relacji dwukierunkowej Odnosi się do strony będącej jej właścicielem
inversedBy : put into Strona będąca właścicielem relacji dwukierunkowej Odnosi się do jej odwrotnej strony
I
mappedBy atrybut używany z deklaracją mapowania OneToOne, OneToMany lub ManyToMany.
InversedBy atrybut używany z deklaracją mapowania OneToOne, ManyToOne lub ManyToMany.
Uwaga : Strona będąca właścicielem relacji dwukierunkowej, strona zawierająca klucz obcy.
są tam dwie wzmianki o inversedBy i mappedBy w Doctrine Documentation: First Link , Second Link
źródło
5.9.1. Posiadanie i odwrotna strona
W przypadku asocjacji wiele do wielu możesz wybrać, który byt jest właścicielem, a który odwrotnie. Z punktu widzenia deweloperów istnieje bardzo prosta reguła semantyczna, która decyduje, która strona jest bardziej odpowiednia do pełnienia roli właściciela. Wystarczy zadać sobie pytanie, który podmiot jest odpowiedzialny za zarządzanie połączeniem i wybrać go jako właściciela.
Weź przykład dwóch podmiotów Artykuł i Tag. Ilekroć chcesz połączyć artykuł z tagiem i odwrotnie, to głównie artykuł jest odpowiedzialny za tę relację. Za każdym razem, gdy dodajesz nowy artykuł, chcesz połączyć go z istniejącymi lub nowymi tagami. Twój formularz tworzenia artykułu prawdopodobnie będzie wspierał to pojęcie i pozwoli bezpośrednio określić tagi. Dlatego powinieneś wybrać artykuł jako stronę właściciela, ponieważ dzięki temu kod jest bardziej zrozumiały:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
źródło