Doctrine2-Tips : Différence entre versions
(→Générer les tables) |
(→Base de donnée) |
||
| (9 révisions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 149 : | Ligne 149 : | ||
== Base de donnée == | == Base de donnée == | ||
| + | |||
| + | ===Configurer la base de donnée=== | ||
| + | La base de donnée se configure dans le fichier {{ File | app/config/parameters.yml }} | ||
| + | <br> | ||
| + | <syntaxhighlight lang=yaml> | ||
| + | parameters: | ||
| + | database_host: 127.0.0.1 | ||
| + | database_port: null | ||
| + | database_name: symfonydb | ||
| + | database_user: symfony_user | ||
| + | database_password: symfony | ||
| + | mailer_transport: smtp | ||
| + | mailer_host: 127.0.0.1 | ||
| + | mailer_user: null | ||
| + | mailer_password: null | ||
| + | </syntaxhighlight> | ||
===Créer la base de donnée === | ===Créer la base de donnée === | ||
| Ligne 163 : | Ligne 179 : | ||
<br> | <br> | ||
{{Console | 1=php app/console doctrine:schema:update --force }} | {{Console | 1=php app/console doctrine:schema:update --force }} | ||
| + | <br> | ||
| + | |||
| + | === Mise à jour === | ||
| + | <br> | ||
| + | {{ Console | 1=php app/console doctrine:schema:update }} | ||
<br> | <br> | ||
=== Relations === | === Relations === | ||
| + | ==== One To One ==== | ||
| + | <br> | ||
| + | [[Fichier:Doctrinne2-onetoone.png|centré]] | ||
| + | <br> | ||
| − | |||
<syntaxhighlight lang=php> | <syntaxhighlight lang=php> | ||
<?php | <?php | ||
| Ligne 201 : | Ligne 225 : | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | ==== Many To One ==== | ||
| + | <br> | ||
| + | [[Fichier:Doctrine2-manytoone.png|centré]] | ||
| + | <br> | ||
| + | |||
| + | <syntaxhighlight lang=php> | ||
| + | <?php | ||
| + | // src/OC/PlatformBundle/Entity/Application.php | ||
| + | |||
| + | /** | ||
| + | * @ORM\Entity | ||
| + | */ | ||
| + | class Application | ||
| + | { | ||
| + | /** | ||
| + | * @ORM\ManyToOne(targetEntity="OC\PlatformBundle\Entity\Advert") | ||
| + | * @ORM\JoinColumn(nullable=false) | ||
| + | */ | ||
| + | private $advert; | ||
| + | |||
| + | // … | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | <syntaxhighlight lang=php> | ||
| + | <?php | ||
| + | // src/OC/PlatformBundle/Entity/Advert.php | ||
| + | |||
| + | /** | ||
| + | * @ORM\Entity | ||
| + | */ | ||
| + | class Advert | ||
| + | { | ||
| + | // Nul besoin de rajouter de propriété, ici | ||
| + | |||
| + | // … | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ==== Many To Many ==== | ||
| + | <br> | ||
| + | [[Fichier:Doctrine2-manytomany.png|centré]] | ||
| + | <br> | ||
| + | |||
| + | <syntaxhighlight lang=php> | ||
| + | <?php | ||
| + | // src/OC/PlatformBundle/Entity/Advert.php | ||
| + | |||
| + | /** | ||
| + | * @ORM\Entity | ||
| + | */ | ||
| + | class Advert | ||
| + | { | ||
| + | /** | ||
| + | * @ORM\ManyToMany(targetEntity="OC\PlatformBundle\Entity\Category", cascade={"persist"}) | ||
| + | */ | ||
| + | private $categories; | ||
| + | |||
| + | // … | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | <br> | ||
| + | |||
| + | <syntaxhighlight lang=php> | ||
| + | <?php | ||
| + | // src/OC/PlatformBundle/Entity/Category.php | ||
| + | |||
| + | /** | ||
| + | * @ORM\Entity | ||
| + | */ | ||
| + | class Category | ||
| + | { | ||
| + | // Nul besoin d'ajouter une propriété ici | ||
| + | |||
| + | // … | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | <br> | ||
| + | J'ai mis Advert comme propriétaire de la relation. C'est un choix que vous pouvez faire comme bon vous semble ici. Mais récupérer les catégories d'une annonce se fera assez souvent, alors que récupérer les annonces d'une catégorie moins. Et puis, pour récupérer les annonces d'une catégorie, on aura sûrement besoin de personnaliser la requête, donc on le fera de toute façon depuis le CategoryRepository, on en reparlera. | ||
| + | <br> | ||
| + | |||
| + | == Fixtures == | ||
| + | |||
| + | === Installation === | ||
| + | |||
| + | * Pour installer le bundle fixtures, on passe via la commande composer : | ||
| + | <br> | ||
| + | {{ Console | composer require --dev doctrine/doctrine-fixtures-bundle }} | ||
| + | <br> | ||
| + | |||
| + | * On ajoute la ligne dans le fichier {{ File | app/AppKernel.php}} pour activer le bundle | ||
| + | <syntaxhighlight lang=php> | ||
| + | // app/AppKernel.php | ||
| + | // ... | ||
| + | |||
| + | class AppKernel extends Kernel | ||
| + | { | ||
| + | public function registerBundles() | ||
| + | { | ||
| + | // ... | ||
| + | if (in_array($this->getEnvironment(), array('dev', 'test'))) { | ||
| + | $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(); | ||
| + | } | ||
| + | |||
| + | return $bundles | ||
| + | } | ||
| + | |||
| + | // ... | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | <br> | ||
| + | === Utilisation === | ||
| + | Tout d'abord, créons notre fichier de fixture pour l'entité Category. Les fixtures d'un bundle se trouvent dans le répertoire DataFixtures/ORM (ou ODM pour des documents). Voici à quoi ressemble notre fixture LoadCategory | ||
| + | |||
| + | <syntaxhighlight lang=php> | ||
| + | <?php | ||
| + | // src/OC/PlatformBundle/DataFixtures/ORM/LoadCategory.php | ||
| + | |||
| + | namespace OC\PlatformBundle\DataFixtures\ORM; | ||
| + | |||
| + | use Doctrine\Common\DataFixtures\FixtureInterface; | ||
| + | use Doctrine\Common\Persistence\ObjectManager; | ||
| + | use OC\PlatformBundle\Entity\Category; | ||
| + | |||
| + | class LoadCategory implements FixtureInterface | ||
| + | { | ||
| + | // Dans l'argument de la méthode load, l'objet $manager est l'EntityManager | ||
| + | public function load(ObjectManager $manager) | ||
| + | { | ||
| + | // Liste des noms de catégorie à ajouter | ||
| + | $names = array( | ||
| + | 'Développement web', | ||
| + | 'Développement mobile', | ||
| + | 'Graphisme', | ||
| + | 'Intégration', | ||
| + | 'Réseau' | ||
| + | ); | ||
| + | |||
| + | foreach ($names as $name) { | ||
| + | // On crée la catégorie | ||
| + | $category = new Category(); | ||
| + | $category->setName($name); | ||
| + | |||
| + | // On la persiste | ||
| + | $manager->persist($category); | ||
| + | } | ||
| + | |||
| + | // On déclenche l'enregistrement de toutes les catégories | ||
| + | $manager->flush(); | ||
| + | } | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | On éxécute la commande suivante : | ||
| + | <pre> | ||
| + | php app/console doctrine:fixtures:load | ||
| + | Careful, database will be purged. Do you want to continue y/N ?y | ||
| + | > purging database | ||
| + | > loading OC\PlatformBundle\DataFixtures\ORM\LoadCategory | ||
| + | </pre> | ||
| + | <br> | ||
| + | {{ Note | Attention, comme vous avez pu le voir, l'exécution de la commande Doctrine pour insérer les fixtures vide totalement la base de données avant d'insérer les nouvelles données. Si vous voulez ajouter les fixtures en plus des données déjà présentes, il faut ajouter l'option --append à la commande précédente. Cependant, c'est rarement ce que vous voulez, car à la prochaine exécution des fixtures, vous allez insérer une nouvelle fois les mêmes catégories… }} | ||
| + | <br> | ||
[[Catégorie:Doctrine2]] | [[Catégorie:Doctrine2]] | ||
Version actuelle datée du 16 décembre 2015 à 09:53
Sommaire
Entité
Générer une entitée
Welcome to the Doctrine2 entity generator
This command helps you generate Doctrine2 entities.
First, you need to give the entity name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post.
The Entity shortcut name:_
Grâce à ce que le générateur vous dit, vous l'avez compris, il faut entrer le nom de l'entité sous le format NomBundle:NomEntité. Dans notre cas, on entre donc OCPlatformBundle:Advert.
The Entity shortcut name: OCPlatformBundle:Advert
Determine the format to use for the mapping information.
Configuration format (yml, xml, php, or annotation) [annotation]:_
Comme je vous l'ai dit, nous allons utiliser les annotations, qui sont d'ailleurs le format par défaut. Appuyez juste sur la touche Entrée.
Configuration format (yml, xml, php, or annotation) [annotation]:
Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).
Available types: array, simple_array, json_array, object,
boolean, integer, smallint, bigint, string, text, datetime, datetimetz,
date, time, decimal, float, blob, guid.
New field name (press <return> to stop adding fields):_
On commence à saisir le nom de nos champs. Lisez bien ce qui est inscrit avant : Doctrine2 va ajouter automatiquement l'id, de ce fait, pas besoin de le redéfinir ici. On entre donc notre date : date.
New field name (press <return> to stop adding fields): date
Field type [string]:_
C'est maintenant que l'on va dire à Doctrine à quel type correspond notre propriété date. La liste des types possibles vous est donné par Symfony juste au dessus. Nous voulons une date avec les informations de temps, tapez donc datetime.
Répétez les points 3 et 4 pour les propriétés title, author et content. title et author sont de type string de 255 caractères (pourquoi pas). Content est par contre de type text.
New field name (press <return> to stop adding fields): date
Field type [string]: datetime
New field name (press <return> to stop adding fields): title
Field type [string]: string
Field length [255]: 255
New field name (press <return> to stop adding fields): author
Field type [string]: string
Field length [255]: 255
New field name (press <return> to stop adding fields): content
Field type [string]: text
New field name (press <return> to stop adding fields):_
Lorsque vous avez fini, appuyez sur la touche Entrée.
New field name (press <return> to stop adding fields):
Do you want to generate an empty repository class [no]?_
Oui, on va créer le repository associé, c'est très pratique, nous en reparlerons largement. Entrez donc yes.
Confirmez la génération, et voilà !
Do you want to generate an empty repository class [no]? yes
Summary before generation
You are going to generate a "OCPlatformBundle:Advert" Doctrine2 entity
using the "annotation" format.
Do you confirm generation [yes]?
Entity generation
Generating the entity code: OK
You can now start using the generated code!
C:\wamp\www\Symfony>_
Allez tout de suite voir le résultat dans le fichier Entity/Advert.php. Symfony2 a tout généré, même les getters et les setters ! Vous êtes l'heureux propriétaire d'une simple classe… avec plein d'annotations !
Mettre à jour une entité
Enregistrer en BDD
- Création de l'entité
$advert = new Advert();
- Récupération de l'EntityManager
$em = $this->getDoctrine()->getManager();
- On dit à Doctrine de « persister » l'entité. Cela veut dire qu'à partir de maintenant cette entité (qui n'est qu'un simple objet !) est gérée par Doctrine. Cela n'exécute pas encore de requête SQL, ni rien d'autre.
$em->persist($advert);
- On dit à Doctrine d'exécuter effectivement les requêtes nécessaires pour sauvegarder les entités qu'on lui a dit de persister précédemment.
$em->flush();
- Notre Advert étant maintenant enregistré en base de données grâce au flush(), Doctrine2 lui a attribué un id ! On peut donc utiliser $advert->getId() dans la génération de la route, et non un nombre fixe comme précédemment.
Base de donnée
Configurer la base de donnée
La base de donnée se configure dans le fichier app/config/parameters.yml
parameters:
database_host: 127.0.0.1
database_port: null
database_name: symfonydb
database_user: symfony_user
database_password: symfony
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: nullCréer la base de donnée
Création de la requête
Générer les tables
Mise à jour
Relations
One To One
<?php
// src/OC/PlatformBundle/Entity/Advert.php
/**
* @ORM\Entity
*/
class Advert
{
/**
* @ORM\OneToOne(targetEntity="OC\PlatformBundle\Entity\Image", cascade={"persist"})
*/
private $image;
// …
}
<?php
// src/OC/PlatformBundle/Entity/Image
/**
* @ORM\Entity
*/
class Image
{
// Nul besoin d'ajouter une propriété ici
// …
}Many To One
<?php
// src/OC/PlatformBundle/Entity/Application.php
/**
* @ORM\Entity
*/
class Application
{
/**
* @ORM\ManyToOne(targetEntity="OC\PlatformBundle\Entity\Advert")
* @ORM\JoinColumn(nullable=false)
*/
private $advert;
// …
}
<?php
// src/OC/PlatformBundle/Entity/Advert.php
/**
* @ORM\Entity
*/
class Advert
{
// Nul besoin de rajouter de propriété, ici
// …
}Many To Many
<?php
// src/OC/PlatformBundle/Entity/Advert.php
/**
* @ORM\Entity
*/
class Advert
{
/**
* @ORM\ManyToMany(targetEntity="OC\PlatformBundle\Entity\Category", cascade={"persist"})
*/
private $categories;
// …
}
<?php
// src/OC/PlatformBundle/Entity/Category.php
/**
* @ORM\Entity
*/
class Category
{
// Nul besoin d'ajouter une propriété ici
// …
}
J'ai mis Advert comme propriétaire de la relation. C'est un choix que vous pouvez faire comme bon vous semble ici. Mais récupérer les catégories d'une annonce se fera assez souvent, alors que récupérer les annonces d'une catégorie moins. Et puis, pour récupérer les annonces d'une catégorie, on aura sûrement besoin de personnaliser la requête, donc on le fera de toute façon depuis le CategoryRepository, on en reparlera.
Fixtures
Installation
- Pour installer le bundle fixtures, on passe via la commande composer :
- On ajoute la ligne dans le fichier app/AppKernel.php pour activer le bundle
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
public function registerBundles()
{
// ...
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
}
return $bundles
}
// ...
}
Utilisation
Tout d'abord, créons notre fichier de fixture pour l'entité Category. Les fixtures d'un bundle se trouvent dans le répertoire DataFixtures/ORM (ou ODM pour des documents). Voici à quoi ressemble notre fixture LoadCategory
<?php
// src/OC/PlatformBundle/DataFixtures/ORM/LoadCategory.php
namespace OC\PlatformBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use OC\PlatformBundle\Entity\Category;
class LoadCategory implements FixtureInterface
{
// Dans l'argument de la méthode load, l'objet $manager est l'EntityManager
public function load(ObjectManager $manager)
{
// Liste des noms de catégorie à ajouter
$names = array(
'Développement web',
'Développement mobile',
'Graphisme',
'Intégration',
'Réseau'
);
foreach ($names as $name) {
// On crée la catégorie
$category = new Category();
$category->setName($name);
// On la persiste
$manager->persist($category);
}
// On déclenche l'enregistrement de toutes les catégories
$manager->flush();
}
}On éxécute la commande suivante :
php app/console doctrine:fixtures:load Careful, database will be purged. Do you want to continue y/N ?y > purging database > loading OC\PlatformBundle\DataFixtures\ORM\LoadCategory
Attention, comme vous avez pu le voir, l'exécution de la commande Doctrine pour insérer les fixtures vide totalement la base de données avant d'insérer les nouvelles données. Si vous voulez ajouter les fixtures en plus des données déjà présentes, il faut ajouter l'option --append à la commande précédente. Cependant, c'est rarement ce que vous voulez, car à la prochaine exécution des fixtures, vous allez insérer une nouvelle fois les mêmes catégories…



