Mon premier projet en Symfony2 PART2 – Création de la base de données et du model Doctrine2

Posted on octobre 19th, 2011. Written by Rémy Jardinet.

Bon, vous êtes prêt à attaquer la deuxième partie de ce tutoriel ?

Nous allons donc maintenant créer l’architecture de notre projet, sa base de données ainsi que son model.

 

La première chose à savoir est qu’en Symfony2, la notion de « model » comme pour Symfony première version n’existe plus. Cette notion est remplacée par Entity en Sf2.

Et oui comme en Java, cela va être d’ailleurs le cas pour beaucoup de choses. En effet, cette mouture de Symfony est très inspirée du model de fonctionnement de Java avec Spring (injection de dépendances, EntityManager…). Nous verrons tout cela dans les détails au fur et à mesure.

Bref commençons notre projet, et la première chose qu’il nous faut c’est…. un projet ! :)

Et voila ce que nous allons représenter:

 

 

 

 

 

 

Voila, histoire de faire quelque chose d’intéressant, nous allons modéliser le schéma d’un data-center.

  • Un datacenter est composé de plusieurs Baie.
  • Une Baie contient plusieurs serveur.
  • Un serveur est utilisé par un ou plusieurs utilisateurs
  • Un serveur peut être une VirtualMachine, c’est a dire posséder des serveurs « logiques ».
Voila, c’est quelque chose de simple, mais qui va nous permettre de toucher un peu a tout les types de relations.
Alors, nous allons tout simplement commencer par la création de notre Bundle, qui s’appellera MyProjectBundle:
./app/console generate:bundle
La création est interactive, il vous suffit de suivre les instructions:
Bundle namespace: Clycks/MyProjectBundle
Bundle name [ClycksMyProjectBundle]: (taper entrer)
Target directory [/home/clycks/sites/symfony-standard/src]: (taper entrer)
Configuration format : C’est comme vous le sentez, pour ce tutos j’ai choisis Yml car c’est plus proche de ce que je connais en Sf1, apres c’est vous qui voyez.
Pour infos, le changement ce trouve de le fichier « ClycksMyProjectExtension.php » dans DependencyInjection ou il charge au choix un fichier yml, xml ….
Pour la suite, tapez entrer pour le reste des questions.
Voila, votre architecture de Bundle est prête. Nous allons pouvoir passer à la génération de notre base de données.
Premier changement de entre Sf1 et Sf2, l’ORM est passé a Doctrine2. Une nouvelle version qui comme Sf2 intègre pas mal de changements. Premièrement, comme je l’avais expliqué précédemment, la notion d’objet en Doctrine 2 est une Entity. Ce qui implique aussi que chaque entity a son propre fichier de modélisation yml à l’instar de Sf2 ou tout était dans le même fichier (schema.yml).
Nous allons donc créer notre première entité: Datacenter.
./app/console doctrine:generate:entity

On vous demande le nom de votre Entité, accolé au namespace de votre projet ClycksMyProjectBundle

The Entity shortcut name: ClycksMyProjectBundle:Datacenter

Pour l’annotation, encore une fois nous allons prendre l’yml, pour bien voir la différence avec Sf2 sans être trop perdu.

Configuration format (yml, xml, php, or annotation) [annotation]: yml
Ensuite, l’invité de commande nous demande si nous voulons ajouter des champs directement. C’est assez simple et rapide, sauf que nous pouvons pas tout regler (unique, notnull etc…)
Je tape donc entrer, nous rentrerons les champs à la main comme des grands ;)
Vous pouvez valider toutes les autres étapes jusqu’à la fin.
Great ! Vous avez créé votre première entité.
Il vous faut recommencer ceci avec les trois autres entités : Server, Bay, Customer
Nous allons donc maintenant les configurer pour ajouter les champs manquants etc…
Ouvrons le fichier Datacenter.orm.yml
## src/Clycks/MyProjectBundle/Ressources/config/doctrine/ ##

Clycks\MyProjectBundle\Entity\Datacenter:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
  lifecycleCallbacks: {  }
Les fichiers présents dans ce répertoire doctrine sont les fichiers de générations des entités. Ils correspondent aux fichiers schema.yml de Sf1.
Voyons ligne par ligne à quoi correspond ce fichier:
Clycks\MyProjectBundle\Entity\Datacenter
C’est la référence de l’entity à quoi correspond ce model YAML. Ici nous avons bien ce que nous avons demandé tout à l’heure en ligne de commande.
  type: entity
Dans ces cas ci, ce sera toujours entity, mais cela peut changer si vous faite de l’ODM par exemple avec Mango DB
  table: null

Si vous voulez définir un nom de table en BDD spécifique, c’est ici que ça ce passe. Par defaut il prendra le nom de l’entité avec les majuscules

fields:

Et enfin voici la déclaration de nos champs. On peut voir que par defaut, le champ Id est créé

Nous allons donc ajouter nos champs sur cette entité:

Clycks/MyProjectBundle/Entity/Datacenter
  type: entity
  table: hp_datacenter
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    location:
      type: string

Maintenant, il va être temps de voir les relations pour pouvoir lier nos éléments.

Pour cela, Doctrine2 est légérement différent de Doctrine1 mais surtout plus simple (une fois que l’on a compris le truc).

Cela marche avec 4 mots clefs dans le yaml:

  • oneToOne
  • oneToMany
  • manyToOne
  • manyToMany
Je pense que je n’ai pas besoin spécialement de présenter ce que chaque mot veut dire, si jamais vous vous interrogez, la doc c’est ici
Bref, voyons comment utiliser ces mots clefs.
Nous allons lier notre table Datacenter à notre table Bay. C’est à dire une Bay peut contenir plusieurs serveurs:
Clycks\MyProjectBundle\Entity\Datacenter:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    location:
      type: string
  oneToMany:
    bay:
      targetEntity: Bay
      mappedBy: datacenter
  lifecycleCallbacks: {  }
Voila, simple non ?
Tout d’abord:
    bay:

Cela est le nom de notre relation, c’est grâce à ce nom que dans le code plus tard,  nous récupérerons à partir d’un Datacenter les Bay associées.

      targetEntity: Bay

L’entité visée pour la liaison.

      mappedBy: datacenter

C’est l’inverse du premier bay, c’est pour obtenir les datacenters à partir d’un élément Bay.

Du coup, nous allons mettre la relations inverse dans le fichier Bay.orm.yml

Clycks\MyProjectBundle\Entity\Bay:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    space:
      type: integer
      default: 0
  manyToOne:
    datacenter:
      targetEntity: Datacenter
  lifecycleCallbacks: {  }

Voila, notre liaison est faite !

Voici toute les configurations orm pour nos entités:

Clycks\MyProjectBundle\Entity\Datacenter:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    location:
      type: string
  oneToMany:
    bay:
      targetEntity: Bay
      mappedBy: datacenter
  lifecycleCallbacks: {  }

 

Clycks\MyProjectBundle\Entity\Bay:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    space:
      type: integer
      default: 0
  manyToOne:
    datacenter:
      targetEntity: Datacenter
  oneToMany:
    machine:
      targetEntity: Server
      mappedBy: bay
  lifecycleCallbacks: {  }

 

Clycks\MyProjectBundle\Entity\Server:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    name:
      type: string
      lenght: 255
      notnull: true
    hdd_size:
      type: string
      lenght: 50
      notnull: false
    nb_disk:
      type: integer
      default: 1
      notnull: false
    ram:
      type: string
      lenght: 255
      notnull: false
    cpu:
      type: string
      lenght: 255
      notnull: false
    os:
      type: string
      lenght: 255
      notnull: false
  oneToMany:
    children:
      targetEntity: Server
      mappedBy: parent
  manyToOne:
    parent:
      targetEntity: Server
      inversedBy: children
    bay:
      targetEntity: Bay
  manyToMany:
    customers:
      targetEntity: Customer
      inversedBy: servers
      joinTable:
        name: customer_server
        joinColumns:
          server_id:
            referencedColumnName: id
        inverseJoinColumns:
          customer_id:
            referencedColumnName: id
  lifecycleCallbacks: {  }

 

Clycks\MyProjectBundle\Entity\Customer:
  type: entity
  table: null
  fields:
    id:
      type: integer
      id: true
      generator:
        strategy: AUTO
    username:
      type: string
      lenght: 255
    address:
      type: string
      lenght: 4000
    zip:
      type: string
      lenght: 20
    city:
      type: string
      lenght: 255
  lifecycleCallbacks: {  }

Vous voyez surement quelque chose de bizarre sur Server. C’est en fait une relation oneToMany sur lui même. Pourquoi ? Tout simplement pour gérer le cas des machines virtuelles.

A noter que si vous voulez que relation soit obligatoire, dans le cas d’une oneToOne par exemple, il vous faudra ajouter ceci dans votre yaml au niveau de la joinColumn :

      joinColumn:
        name: server_id
        nullable: false
        referencedColumnName: id

Nullable a false !

 

Voila, nous pouvons passer à la génération des fichiers de class PHP :

./app/console generate:doctrine:entities ClycksMyProjectBundle

 

Nous y voila, vous avez créé des entités Symfony2 avec Doctrine. Vous pouvez dès à présent travailler sur vos données (Insert, Select ….).

Mais aussi, grâce à un admin Générator, SonataAdminBundle

Dans un prochaine article, nous verrons comment instancier un admin generator avec Sonata et comment s’en servir. (Article en cours de rédaction)

This entry was posted on Mercredi, octobre 19th, 2011 at 08:50 and is filed under Symfony, Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. You can leave a response, or trackback from your own site.

Rémy Jardinet

6 Responses »

  1. Je suis vraiment sceptique sur le besoin de passer à sf2 à partir de sf1.4. Les changements ne sont qu’architecturaux, il n’y a que tres peu d’apport en fonctionnalités. Es-ce que ca vaut vraiment la peine ?

    • Disons que comme toute technologie, il faut pouvoir suivre le fil de l’avancement. Sf 1.4.x ne sera pas maintenue éternellement et commence tres sérieusement à stagner en terme de fonctionnalités depuis bien un an.
      Pour ce qui est de la solution en elle même, le gain en performance et visible sur de grosses applications web (de l’ordre de 20% ou plus). C’est certe pas grand chose mais cependant pas négligeable pour le futur.

      Enfin, le dernier point intéressant avec Sf2, c’est qui l’est bien plus ouvert au développeur, que ce soit pour le core en lui même, ou bien pour les plugins.

      Pour t’en convaincre, je t’invite a jeter un coup d’oeil sur ce site, et de voir a la vitesse ou évolue les bundles:
      http://symfony2bundles.org/

  2. Dommage le tutoriel n’est pas disponible.
    Pour bientôt ?

  3. Merci à toi! (sincèrement)

    ..mais si je peux me permettre… en écrivant en blanc sur blanc, ce serait plus classe encore, mais on ne verrait vraiment pus rien…

    Perso, je me casse les yeux… (le bouton ‘envoyer’ un message, lui, est parfait!)

  4. Salut,

    J’attend le tuto avec l’integration de sonatAdmin.

    C’est vrai que c’est pas lisible gris sur blanc, ou alors un gris fonce.

    Merci.

Laisser un commentaire

Please note: comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Catégories

Suivez nous!

Calendrier

octobre 2011
L Ma Me J V S D
« sept   nov »
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Qui somme nous?

Clycks est une société de service qui aide les jeunes entreprises à entrer dans le monde du web.