ORM
Note
si vous voulez générer automatiquement les modèles, consultez la partie génération des modèles .
Une classe de type modèle est juste un bon vieil objet php sans héritage.
Les modèles sont situés par défaut dans le dossier appmodels.
Le mappage relationnel d’objets (ORM) repose sur les annotations ou les attributs des membres (depuis PHP8) dans la classe du modèle.
Définition de modèles
Un modèle basique
Un modèle doit définir sa clé primaire en utilisant l’annotation @id sur les membres concernés.
Les membres sérialisés doivent avoir des getters et setters.
Sans autre annotation, une classe correspond à une table du même nom dans la base de données, chaque membre correspond à un champ de cette table.
1namespace models;
2
3use Ubiquity\attributes\items\Id;
4
5class User{
6
7 #[Id]
8 private $id;
9
10 private $firstname;
11
12 public function getFirstname(){
13 return $this->firstname;
14 }
15 public function setFirstname($firstname){
16 $this->firstname=$firstname;
17 }
18}
1 namespace models;
2
3 class User{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $firstname;
10
11 public function getFirstname(){
12 return $this->firstname;
13 }
14 public function setFirstname($firstname){
15 $this->firstname=$firstname;
16 }
17 }
Mappage
Table->Classe
Si le nom de la table est différent du nom de la classe, l’annotation @table permet de préciser le nom de la table.
1namespace models;
2
3use Ubiquity\attributes\items\Table;
4use Ubiquity\attributes\items\Id;
5
6#[Table('user')]
7class User{
8
9 #[Id]
10 private $id;
11
12 private $firstname;
13
14 public function getFirstname(){
15 return $this->firstname;
16 }
17 public function setFirstname($firstname){
18 $this->firstname=$firstname;
19 }
20}
1namespace models;
2
3/**
4 * @table("name"=>"user")
5 */
6class User{
7 /**
8 * @id
9 */
10 private $id;
11
12 private $firstname;
13
14 public function getFirstname(){
15 return $this->firstname;
16 }
17 public function setFirstname($firstname){
18 $this->firstname=$firstname;
19 }
20}
Champ->Membre
Si le nom d’un champ est différent du nom du membre de la classe associé, l’annotation @column permet de spécifier un nom de champ différent.
1namespace models;
2
3use Ubiquity\attributes\items\Table;
4use Ubiquity\attributes\items\Id;
5use Ubiquity\attributes\items\Column;
6
7#[Table('user')
8class User{
9
10 #[Id]
11 private $id;
12
13 #[Column('column_name')]
14 private $firstname;
15
16 public function getFirstname(){
17 return $this->firstname;
18 }
19 public function setFirstname($firstname){
20 $this->firstname=$firstname;
21 }
22}
1namespace models;
2
3/**
4 * @table("user")
5 */
6class User{
7 /**
8 * @id
9 */
10 private $id;
11
12 /**
13 * column("user_name")
14 */
15 private $firstname;
16
17 public function getFirstname(){
18 return $this->firstname;
19 }
20 public function setFirstname($firstname){
21 $this->firstname=$firstname;
22 }
23}
Associations
Note
Convention de nommage
Les noms des champs des clés étrangères sont constitués du nom de la clé primaire de la table référencée suivi du nom de la table référencée dont la première lettre est en majuscule.
Exemple : idUser
pour la table user
dont la clé primaire est id
.
ManyToOne
Un utilisateur appartient à une organisation :
1 namespace models;
2
3use Ubiquity\attributes\items\ManyToOne;
4use Ubiquity\attributes\items\Id;
5use Ubiquity\attributes\items\JoinColumn;
6
7 class User{
8
9 #[Id]
10 private $id;
11
12 private $firstname;
13
14 #[ManyToOne]
15 #[JoinColumn(className: \models\Organization::class, name: 'idOrganization', nullable: false)]
16 private $organization;
17
18 public function getOrganization(){
19 return $this->organization;
20 }
21
22 public function setOrganization($organization){
23 $this->organization=$organization;
24 }
25}
1 namespace models;
2
3 class User{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $firstname;
10
11 /**
12 * @manyToOne
13 * @joinColumn("className"=>"models\\Organization","name"=>"idOrganization","nullable"=>false)
14 */
15 private $organization;
16
17 public function getOrganization(){
18 return $this->organization;
19 }
20
21 public function setOrganization($organization){
22 $this->organization=$organization;
23 }
24}
L’annotation @joinColumn ou l’attribut JoinColumn le spécifie :
Le membre $organisation est une instance de modelsOrganization.
La table user possède une clé étrangère idOrganization faisant référence à la clé primaire de l’organisation.
Cette clé étrangère n’est pas nulle => un utilisateur aura toujours une organisation.
OneToMany
Une organisation a de nombreux utilisateurs :
1namespace models;
2
3use Ubiquity\attributes\items\OneToMany;
4use Ubiquity\attributes\items\Id;
5
6class Organization{
7
8 #[Id]
9 private $id;
10
11 private $name;
12
13 #[OneToMany(mappedBy: 'organization', className: \models\User::class)]
14 private $users;
15}
1namespace models;
2
3class Organization{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $name;
10
11 /**
12 * @oneToMany("mappedBy"=>"organization","className"=>"models\\User")
13 */
14 private $users;
15}
Dans ce cas, l’association est bidirectionnelle.
L’annotation @oneToMany doit juste préciser :
La classe de chaque utilisateur dans le tableau users : modelsUser.
la valeur de @mappedBy est le nom de l’attribut association-mapping du côté propriétaire : $organisation dans la classe User.
ManyToMany
Un utilisateur peut appartenir à des groupes.
Un groupe se compose de plusieurs utilisateurs.
1namespace models;
2
3use Ubiquity\attributes\items\ManyToMany;
4use Ubiquity\attributes\items\Id;
5use Ubiquity\attributes\items\JoinTable;
6
7class User{
8
9 #[Id]
10 private $id;
11
12 private $firstname;
13
14 #[ManyToMany(targetEntity: \models\Group::class, inversedBy: 'users')]
15 #[JoinTable(name: 'groupusers')]
16 private $groups;
17
18}
1namespace models;
2
3class User{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $firstname;
10
11 /**
12 * @manyToMany("targetEntity"=>"models\\Group","inversedBy"=>"users")
13 * @joinTable("name"=>"groupusers")
14 */
15 private $groups;
16
17}
1namespace models;
2
3use Ubiquity\attributes\items\ManyToMany;
4use Ubiquity\attributes\items\Id;
5use Ubiquity\attributes\items\JoinTable;
6
7class Group{
8
9 #[Id]
10 private $id;
11
12 private $name;
13
14 #[ManyToMany(targetEntity: \models\User::class, inversedBy: 'groups')]
15 #[JoinTable(name: 'groupusers')]
16 private $users;
17
18}
1namespace models;
2
3class Group{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $name;
10
11 /**
12 * @manyToMany("targetEntity"=>"models\\User","inversedBy"=>"groups")
13 * @joinTable("name"=>"groupusers")
14 */
15 private $users;
16
17}
Si les conventions de nommage ne sont pas respectées pour les clés étrangères,
il est possible de spécifier les champs associés.
1namespace models;
2
3use Ubiquity\attributes\items\ManyToMany;
4use Ubiquity\attributes\items\Id;
5use Ubiquity\attributes\items\JoinTable;
6
7class Group{
8
9 #[Id]
10 private $id;
11
12 private $name;
13
14 #[ManyToMany(targetEntity: \models\User::class, inversedBy: 'groupes')]
15 #[JoinTable(name: 'groupeusers',
16 joinColumns: ['name'=>'id_groupe','referencedColumnName'=>'id'],
17 inverseJoinColumns: ['name'=>'id_user','referencedColumnName'=>'id'])]
18 private $users;
19
20}
1namespace models;
2
3class Group{
4 /**
5 * @id
6 */
7 private $id;
8
9 private $name;
10
11 /**
12 * @manyToMany("targetEntity"=>"models\\User","inversedBy"=>"groupes")
13 * @joinTable("name"=>"groupeusers",
14 * "joinColumns"=>["name"=>"id_groupe","referencedColumnName"=>"id"],
15 * "inverseJoinColumns"=>["name"=>"id_user","referencedColumnName"=>"id"])
16 */
17 private $users;
18
19}
Annotations ORM
Annotations pour les classes
@annotation |
rôle |
propriétés |
rôle |
---|---|---|---|
@database |
Définit l’offset de la base de données associée (défini dans le fichier de configuration) |
||
@table |
Définit le nom de la table associée. |
Annotations pour les membres
@annotation |
rôle |
propriétés |
rôle |
---|---|---|---|
@id |
Définit la ou les clés primaires. |
||
@column |
Spécifie les caractéristiques du champ associé. |
name |
Nom du champ associé |
nullable |
true si la valeur peut être nulle |
||
dbType |
Type du champ dans la base de données |
||
@transient |
Indique que le champ n’est pas persistant. |
Associations
@annotation (extends) |
rôle |
properties [optional] |
rôle |
---|---|---|---|
@manyToOne |
Définit une association à valeur unique avec une autre classe d’entité. |
||
@joinColumn (@column) |
Indique la clé étrangère dans l’association manyToOne. |
className |
Classe du membre |
[referencedColumnName] |
Nom de la colonne associée |
||
@oneToMany |
Définit une association à valeurs multiples avec une autre classe d’entité. |
className |
Classe des objets du membre |
[mappedBy] |
Nom de l’attribut de mappage d’association du côté propriétaire. |
||
@manyToMany |
Définit une association à valeurs multiples avec une multiplicité de plusieurs à plusieurs. |
targetEntity |
Classe des objets du membre |
[inversedBy] |
Nom du membre associé du côté inverse |
||
[mappedBy] |
Nom du membre associé du côté propriétaire |
||
@joinTable |
Définit la table d’association pour l’association many-to-many. |
name |
Le nom de la table d’association |
[joinColumns] |
@column => name et referencedColumnName pour ce côté |
||
[inverseJoinColumns] |
@column => name et referencedColumnName pour l’autre côté |