Я разрабатываю свое приложение с использованием Zend Framework 2 и Doctrine 2.
Когда я пишу аннотации, я не могу понять разницу между 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;
Я провел быстрый поиск и нашел следующее, но все еще не понимаю:
php
doctrine-orm
Разработчик
источник
источник
Приведенных выше ответов было недостаточно, чтобы понять, что происходит, поэтому, углубившись в это подробнее, я думаю, что у меня есть способ объяснить это, что будет иметь смысл для людей, которые боролись, как и я, чтобы понять.
InversedBy и mappedBy используются механизмом ВНУТРЕННЕЙ ДОКТРИНЫ, чтобы уменьшить количество SQL-запросов, которые он должен выполнять для получения необходимой информации. Чтобы прояснить ситуацию, если вы не добавите инвертированныйBy или mappedBy, ваш код все равно будет работать, но не будет оптимизирован .
Так, например, посмотрите на классы ниже:
Эти классы, если вы должны запустить команду для генерации схемы (например
bin/console doctrine:schema:update --force --dump-sql
), вы заметите, что в таблице категорий нет столбца для задач. (это потому, что на нем нет аннотации столбца)Здесь важно понимать, что переменные задачи существуют только для того, чтобы внутренний механизм доктрины мог использовать ссылку над ним, в которой указано его mappedBy Category. Теперь ... не путайте здесь, как я ... Категория НЕ относится к ИМЕНИ КЛАССА , это относится к свойству класса Task под названием «protected $ category».
Аналогично, в классе Tasks свойство $ category упоминает, что оно инвертированоBy = "tasks", обратите внимание, что это множественное число, это НЕ МНОЖЕСТВЕННОЕ ЧИСЛО ИМЕНИ КЛАССА , а только потому, что свойство называется 'protected $ tasks' в Категории класс.
Как только вы это поймете, станет очень легко понять, что делают reverseBy и mappedBy и как их использовать в этой ситуации.
Сторона, которая ссылается на внешний ключ, например `` задачи '' в моем примере, всегда получает атрибут инвертированного типа, потому что ей нужно знать, какой класс (с помощью команды targetEntity) и какая переменная (инверседби =) в этом классе будет `` работать в обратном направлении '', чтобы говорить и получать информацию о категории от. Легкий способ запомнить это: класс, который будет иметь foreignkey_id, - это тот, который должен иметь инверсию.
Если, как и в случае с категорией, и ее свойство $ tasks (которого нет в таблице, помните, это только часть класса для целей оптимизации) является MappedBy 'tasks', это создает официальную связь между двумя объектами, так что теперь доктрина может безопасно используйте операторы JOIN SQL вместо двух отдельных операторов SELECT. Без mappedBy механизм доктрины не узнает из оператора JOIN, какую переменную в классе «Задача» создаст, чтобы поместить информацию о категории.
Надеюсь, это немного лучше объясняет.
источник
Category is NOT referring TO THE CLASS NAME, its referring to the property on the Task class called 'protected $category'
все, что мне нужно. Это не только решило мою проблему, но и помогло мне понять. Лучший ответ ИМО :-)В двунаправленных отношениях есть как сторона владения, так и обратная сторона
mappedBy : положить в обратную сторону двунаправленной связи, чтобы ссылаться на свою сторону
reverseBy : поместить во владение стороны двунаправленного отношения, чтобы сослаться на его обратную сторону
И
Атрибут mappedBy, используемый с объявлением сопоставления OneToOne, OneToMany или ManyToMany.
Атрибут инверседби, используемый с объявлением сопоставления OneToOne, ManyToOne или ManyToMany.
Примечание : сторона-владелец двунаправленного отношения - сторона, содержащая внешний ключ.
в документации Doctrine есть две ссылки на reverseBy и mappedBy: первая ссылка , вторая ссылка
источник
5.9.1. Собственная и обратная сторона
Для ассоциаций "многие-ко-многим" вы можете выбрать, какой объект является владельцем, а какой - обратной стороной. Существует очень простое семантическое правило, позволяющее решить, какая сторона больше подходит для роли владельца с точки зрения разработчиков. Вам нужно только спросить себя, какая сущность отвечает за управление подключением, и выбрать ее в качестве владельца.
Возьмем для примера две сущности: Article и Tag. Всякий раз, когда вы хотите связать статью с тегом и наоборот, в основном за это отношение отвечает статья. Каждый раз, когда вы добавляете новую статью, вы хотите связать ее с существующими или новыми тегами. Ваша форма создания статьи, вероятно, будет поддерживать это понятие и позволит напрямую указывать теги. Вот почему вы должны выбрать Статью в качестве владельца, так как это делает код более понятным:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
источник