Jaka jest różnica między inversedBy i mappedBy?

Rozwijam swoją aplikację używając Zend Framework 2 i Doctrine 2.

Pisząc adnotacje, nie jestem w stanie zrozumieć różnicy między mappedBy A inversedBy.

Kiedy należy używać mappedBy?

Kiedy należy używać inversedBy?

Kiedy należy używać obu?

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;

Szybko wyszukałem i znalazłem następujące, ale nadal jestem zdezorientowany:

Author: Community, 2012-09-19

4 answers

  • mappedBy musi być określone na odwróconej stronie asocjacji (dwukierunkowej)
  • inversedBy musi być określone na stronie posiadającej asocjacji (dwukierunkowej)

Z dokumentacji doktryny:

    ManyToOne jest zawsze właścicielem dwukierunkowej asokacji.
  • OneToMany jest zawsze odwrotną stroną dwukierunkowej asokacji.
  • właścicielem strony OneToOne assocation jest encja z tabelą zawierającą klucz obcy.

Zobacz https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/unitofwork-associations.html

 136
Author: Andreas Linden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 18:38:03

Powyższe odpowiedzi nie były dla mnie wystarczające, aby zrozumieć, co się dzieje, więc po zagłębieniu się w to bardziej myślę, że mam sposób na wyjaśnienie tego, że będzie sens dla ludzi, którzy walczyli tak jak ja, aby zrozumieć.

InversedBy i mappedBy są używane przez silnik wewnętrznej doktryny do zmniejszenia liczby zapytań SQL to musi zrobić, aby uzyskać potrzebne informacje. Aby było jasne, jeśli nie dodasz inversedBy lub mappedBy Twój kod będzie nadal działał, ale nie będzie zoptymalizowany.

Więc na przykład, spójrz na klasy poniżej:

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

Te klasy jeśli uruchomisz polecenie do generowania schematu (na przykład bin/console doctrine:schema:update --force --dump-sql) zauważysz, że tabela kategorii nie ma kolumny dla zadań. (dzieje się tak dlatego, że nie ma na nim adnotacji w kolumnie)

Ważną rzeczą do zrozumienia tutaj jest to, że zmienne zadania jest tylko tam, więc wewnętrzny silnik doktryny może użyć odniesienia powyżej, które mówi jego mapped by Category. Teraz... nie bądź zdezorientowany, tak jak ja... kategoria nie odnosi się do nazwy klasy, odnosi się do właściwości klasy zadania o nazwie 'protected $category'.

Podobnie jak wise, na klasie Tasks właściwość $category wspomina, że jest inversedBy="tasks", zauważ, że jest to liczba mnoga, nie jest to liczba mnoga nazwy klasy , ale tylko dlatego, że właściwość nazywa się 'protected $tasks' w klasie Category.

Kiedy zrozumiesz to staje się bardzo łatwe do zrozumienia, co robią inversedBy i mappedBy i jak z nich korzystać w tej sytuacji.

Strona, która odwołuje się do klucza obcego, jak "zadania" w moim przykładzie, zawsze otrzymuje atrybut inversedBy, ponieważ musi wiedzieć, jaka Klasa (poprzez polecenie targetEntity) i jaka zmienna (inversedBy=) na tej klasie, aby "pracować wstecz", że tak powiem i uzyskać informacje o kategorii. Łatwym sposobem na zapamiętanie tego jest klasa, która miałaby foreignkey_id jest taki, który musi być odwrócony.

Gdzie, jak w przypadku category, i jego właściwość $ tasks (która nie jest w tabeli pamiętaj, tylko część klasy dla celów optymalizacji) jest mapowana przez 'tasks', tworzy to oficjalnie relację między dwoma encjami, dzięki czemu doctrine może teraz bezpiecznie używać poleceń JOIN SQL zamiast dwóch oddzielnych poleceń SELECT. Bez mappedBy silnik doctrine nie wiedziałby z instrukcji JOIN, że stworzy jaką zmienną w klasie 'Task' aby umieścić informacje o kategorii.

Mam nadzieję, że to wyjaśni to trochę lepiej.
 44
Author: Joseph Astrahan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 00:55:08

W relacji dwukierunkowej ma zarówno stronę własną, jak i odwrotną

MappedBy: Umieścić w odwrotnej stronie relacji dwukierunkowej, aby odnieść się do jej strony własnej

InversedBy : umieścić na stronie własności relacji dwukierunkowej, aby odnieść się do jej strony odwrotnej

I

Atrybut MappedBy używany z deklaracją mapowania OneToOne, OneToMany lub ManyToMany.

InversedBy atrybut używany z deklaracją mapowania OneToOne, ManyToOne lub ManyToMany.

Notice : Strona własności relacji dwukierunkowej strona, która zawiera klucz obcy.

Istnieją dwa odniesienia o inversedBy i mappedBy do dokumentacji doktryny : Pierwszy Link,Drugi Link

 20
Author: ahmed hamdy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 16:12:38

5.9.1. Strona własna i odwrotna

Dla wielu do wielu skojarzeń można wybrać, który podmiot jest właścicielem, a który stroną odwrotną. Istnieje bardzo prosta reguła semantyczna, aby zdecydować, która strona jest bardziej odpowiednia do bycia właścicielem z perspektywy deweloperów. Musisz tylko zadać sobie pytanie, który podmiot jest odpowiedzialny za zarządzanie połączeniem i wybrać to jako stronę posiadającą.

Weźmy przykład dwóch encji Article I Tag. Gdy chcesz połączyć artykuł do tagu i odwrotnie, to głównie artykuł jest odpowiedzialny za tę relację. Za każdym razem, gdy dodajesz nowy artykuł, chcesz go połączyć z istniejącymi lub nowymi tagami. Twój formularz Utwórz artykuł prawdopodobnie wesprze to pojęcie i pozwoli bezpośrednio określić tagi. Dlatego powinieneś wybrać artykuł jako stronę posiadającą, ponieważ sprawia to, że kod jest bardziej zrozumiały:

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

 1
Author: Micheal Mouner Mikhail Youssif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-25 08:20:38