Je développe mon application en utilisant Zend Framework 2 et Doctrine 2.
En écrivant des annotations, je ne peux pas comprendre la différence entre mappedBy
et inversedBy
.
Quand dois-je utiliser mappedBy
?
Quand dois-je utiliser inversedBy
?
Quand dois-je utiliser ni l'un ni l'autre?
Voici un exemple:
/**
*
* @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;
J'ai fait une recherche rapide et j'ai trouvé ce qui suit, mais je suis toujours confus:
php
doctrine-orm
Développeur
la source
la source
Les réponses ci-dessus n'étaient pas suffisantes pour que je comprenne ce qui se passait, donc après y avoir approfondi davantage, je pense que j'ai un moyen de l'expliquer qui aura du sens pour les personnes qui ont lutté comme moi pour comprendre.
inversedBy et mappedBy sont utilisés par le moteur INTERNAL DOCTRINE pour réduire le nombre de requêtes SQL qu'il doit effectuer pour obtenir les informations dont vous avez besoin. Pour être clair si vous n'ajoutez pas inversedBy ou mappedBy, votre code fonctionnera toujours mais ne sera pas optimisé .
Par exemple, regardez les classes ci-dessous:
Ces classes si vous exécutez la commande pour générer le schéma (par exemple
bin/console doctrine:schema:update --force --dump-sql
), vous remarquerez que la table Category ne contient pas de colonne pour les tâches. (c'est parce qu'il n'a pas d'annotation de colonne)La chose importante à comprendre ici est que les tâches variables sont uniquement là pour que le moteur de doctrine interne puisse utiliser la référence au-dessus de lui qui indique sa catégorie mappedBy. Maintenant ... ne soyez pas confondu ici comme je l'étais ... La catégorie ne fait pas référence au nom de la classe, elle fait référence à la propriété de la classe Task appelée 'protected $ category'.
De même, dans la classe Tasks, la propriété $ category mentionne qu'elle est inversedBy = "tasks", notez que c'est au pluriel, ce n'est PAS LE PLURIEL DU NOM DE LA CLASSE , mais simplement parce que la propriété est appelée 'protected $ tasks' dans la catégorie classe.
Une fois que vous avez compris cela, il devient très facile de comprendre ce que font inversedBy et mappedBy et comment les utiliser dans cette situation.
Le côté qui fait référence à la clé étrangère comme `` tâches '' dans mon exemple obtient toujours l'attribut inversedBy car il a besoin de savoir quelle classe (via la commande targetEntity) et quelle variable (inversedBy =) sur cette classe pour `` travailler en arrière '' pour parler et obtenir les informations sur la catégorie. Un moyen facile de s'en souvenir est que la classe qui aurait le Foreignkey_id est celle qui doit avoir inversedBy.
Où, comme pour la catégorie et sa propriété $ tasks (qui n'est pas sur la table, rappelez-vous, seule une partie de la classe à des fins d'optimisation) est MappedBy `` tâches '', cela crée officiellement la relation entre les deux entités afin que la doctrine puisse maintenant en toute sécurité utilisez des instructions SQL JOIN au lieu de deux instructions SELECT séparées. Sans mappedBy, le moteur de doctrine ne saurait à partir de l'instruction JOIN qu'il créera quelle variable dans la classe 'Task' pour mettre les informations de catégorie.
J'espère que cela explique un peu mieux.
la source
Category is NOT referring TO THE CLASS NAME, its referring to the property on the Task class called 'protected $category'
tout ce dont j'avais besoin. Cela n'a pas seulement résolu mon problème, mais cela m'a aidé à comprendre. La meilleure réponse IMO :-)En relation bidirectionnelle a à la fois un côté propriétaire et un côté inverse
mappedBy : mettre dans Le côté inverse d'une relation bidirectionnelle Pour faire référence à son côté propriétaire
inversedBy : mettre dans Le côté propriétaire d'une relation bidirectionnelle Pour faire référence à son côté inverse
ET
Attribut mappedBy utilisé avec la déclaration de mappage OneToOne, OneToMany ou ManyToMany.
inversedBy attribut utilisé avec le OneToOne, ManyToOne ou ManyToMany déclaration de mise en correspondance.
Remarque : le côté propriétaire d'une relation bidirectionnelle est le côté qui contient la clé étrangère.
il y a deux références sur inversedBy et mappedBy dans Doctrine Documentation: First Link , Second Link
la source
5.9.1. Propriétaire et côté inverse
Pour les associations plusieurs-à-plusieurs, vous pouvez choisir quelle entité est propriétaire et quel côté inverse. Il existe une règle sémantique très simple pour décider quel côté est le plus approprié pour être le côté propriétaire du point de vue des développeurs. Il vous suffit de vous demander quelle entité est responsable de la gestion de la connexion et de la choisir comme propriétaire.
Prenons un exemple de deux entités Article et Tag. Chaque fois que vous souhaitez connecter un article à un tag et vice-versa, c'est surtout l'article qui est responsable de cette relation. Chaque fois que vous ajoutez un nouvel article, vous souhaitez le connecter avec des balises existantes ou nouvelles. Votre formulaire de création d'article supportera probablement cette notion et permettra de spécifier directement les balises. C'est pourquoi vous devez choisir l'article comme côté propriétaire, car cela rend le code plus compréhensible:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
la source