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:
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 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.