Symfony - Doctrine ORM

Dans le framework Web Symfony, le modèle joue un rôle important. Ce sont les entités commerciales. Ils sont soit fournis par les clients, soit extraits de la base de données principale, manipulés conformément aux règles métier et réintégrés dans la base de données. Ce sont les données présentées par Views. Découvrons les modèles et comment ils interagissent avec le système back-end dans ce chapitre.

Modèle de base de données

Nous devons mapper nos modèles aux éléments de la base de données relationnelle principale pour extraire et conserver les modèles en toute sécurité et efficacement. Ce mappage peut être effectué avec un outil de mappage relationnel objet (ORM). Symfony fournit un bundle séparé,DoctrineBundle, qui intègre Symfony avec l'outil ORM de base de données PHP tiers, Doctrine.

Doctrine ORM

Par défaut, le framework Symfony ne fournit aucun composant pour travailler avec les bases de données. Mais, il s'intègre étroitement avecDoctrine ORM. Doctrine contient plusieurs bibliothèques PHP utilisées pour le stockage de base de données et le mappage d'objets.

L'exemple suivant vous aidera à comprendre le fonctionnement de Doctrine, comment configurer une base de données et comment enregistrer et récupérer les données.

Exemple de doctrine ORM

Dans cet exemple, nous allons d'abord configurer la base de données et créer un objet Student, puis y effectuer certaines opérations.

Pour ce faire, nous devons suivre les étapes suivantes.

Étape 1: créer une application Symfony

Créez une application Symfony, dbsample en utilisant la commande suivante.

symfony new dbsample

Étape 2: configurer une base de données

Généralement, les informations de la base de données sont configurées dans le fichier «app / config / parameters.yml».

Ouvrez le fichier et ajoutez les modifications suivantes.

parameter.yml

parameters: 
   database_host: 127.0.0.1 
   database_port: null
   database_name: studentsdb 
   database_user: <user_name> 
   database_password: <password> 
   mailer_transport: smtp 
   mailer_host: 127.0.0.1 
   mailer_user: null 
   mailer_password: null 
   secret: 037ab82c601c10402408b2b190d5530d602b5809 
   
   doctrine: 
      dbal: 
      driver:   pdo_mysql 
      host:     '%database_host%' 
      dbname:   '%database_name%' 
      user:     '%database_user%' 
      password: '%database_password%' 
      charset: utf8mb4

Désormais, Doctrine ORM peut se connecter à la base de données.

Étape 3: créer une base de données

Exécutez la commande suivante pour générer la base de données «studentdb». Cette étape est utilisée pour lier la base de données dans Doctrine ORM.

php bin/console doctrine:database:create

Après avoir exécuté la commande, il génère automatiquement une base de données vide «Studentsdb». Vous pouvez voir la réponse suivante sur votre écran.

Created database `studentsdb` for connection named default

Étape 4: Informations sur la carte

Les informations de mappage ne sont rien d'autre que des "métadonnées". C'est un ensemble de règles qui informe Doctrine ORM exactement comment la classe Student et ses propriétés sont mappées à une table de base de données spécifique.

Eh bien, ces métadonnées peuvent être spécifiées dans un certain nombre de formats différents, y compris YAML, XML ou vous pouvez passer directement la classe Student à l'aide d'annotations. Il est défini comme suit.

Student.php

Ajoutez les modifications suivantes dans le fichier.

<?php  
namespace AppBundle\Entity;  

use Doctrine\ORM\Mapping as ORM;  
/** 
   * @ORM\Entity 
   * @ORM\Table(name = "students") 
*/ 
class Student { 
   /** 
      * @ORM\Column(type = "integer") 
      * @ORM\Id 
      * @ORM\GeneratedValue(strategy = "AUTO") 
   */ 
   private $id;  
    
   /** 
      * @ORM\Column(type = "string", length = 50) 
   */ 
   private $name;  
   
   /** 
     * @ORM\Column(type = "text") 
     */ 
   private $address; 
}

Ici, le nom de la table est facultatif. Si le nom de la table n'est pas spécifié, il sera déterminé automatiquement en fonction du nom de la classe d'entité.

Étape 5: Lier une entité

Doctrine crée des classes d'entités simples pour vous. Cela vous aide à construire n'importe quelle entité.

Exécutez la commande suivante pour générer une entité.

php bin/console doctrine:generate:entities AppBundle/Entity/Student

Ensuite, vous verrez le résultat suivant et l'entité sera mise à jour.

Generating entity "AppBundle\Entity\Student" 
   > backing up Student.php to Student.php~ 
   > generating AppBundle\Entity\Student

Student.php

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM;  
/** 
   * @ORM\Entity 
   * @ORM\Table(name="students") 
*/ 
class Student { 
   /** 
      * @ORM\Column(type="integer") 
      * @ORM\Id 
      * @ORM\GeneratedValue(strategy="AUTO") 
   */ 
   private $id;  
    
   /** 
      * @ORM\Column(type = "string", length = 50) 
   */ 
   private $name; 
    
   /** 
      * @ORM\Column(type = "text") 
   */
   private $address; 
    
   /** 
      * Get id 
      * 
      * @return integer 
   */ 
   public function getId() { 
      return $this->id; 
   }  
    
   /** 
      * Set name 
      * 
      * @param string $name 
      * 
      * @return Student 
   */ 
    
   public function setName($name) { 
      $this->name = $name;  
      return $this; 
   }  
    
   /** 
      * Get name 
      * 
      * @return string 
   */ 
    
   public function getName() { 
      return $this->name; 
   }  
    
   /**
      * Set address 
      * 
      * @param string $address 
      * 
      * @return Student 
   */ 
    
   public function setAddress($address) { 
      $this->address = $address;  
      return $this; 
   }  
    
   /** 
      * Get address 
      * 
      * @return string 
   */ 
   
   public function getAddress() { 
      return $this->address; 
   } 
}

Étape 6: validation de la carte

Après avoir créé des entités, vous devez valider les mappages à l'aide de la commande suivante.

php bin/console doctrine:schema:validate

Il produira le résultat suivant -

[Mapping]  OK - The mapping files are correct. 
[Database] FAIL - The database schema is not in sync with the current mapping file

Puisque nous n'avons pas créé la table des étudiants, l'entité est désynchronisée. Créons la table des étudiants à l'aide de la commande Symfony à l'étape suivante.

Étape 7: créer un schéma

Doctrine peut créer automatiquement toutes les tables de base de données nécessaires à l'entité Student. Cela peut être fait en utilisant la commande suivante.

php bin/console doctrine:schema:update --force

Après avoir exécuté la commande, vous pouvez voir la réponse suivante.

Updating database schema... 
Database schema updated successfully! "1" query was executed

Cette commande compare ce à quoi votre base de données devrait ressembler avec son apparence réelle et exécute les instructions SQL nécessaires pour mettre à jour le schéma de base de données là où il devrait être.

Maintenant, validez à nouveau le schéma à l'aide de la commande suivante.

php bin/console doctrine:schema:validate

Il produira le résultat suivant -

[Mapping]  OK - The mapping files are correct. 
[Database] OK - The database schema is in sync with the mapping files

Étape 8: Getter et setter

Comme vu dans la section Lier une entité, la commande suivante génère tous les getters et setters pour la classe Student.

$ php bin/console doctrine:generate:entities AppBundle/Entity/Student

Étape 9: conserver les objets dans la base de données

Maintenant, nous avons mappé l'entité Student à sa table Student correspondante. Nous devrions maintenant pouvoir conserver les objets Student dans la base de données. Ajoutez la méthode suivante au StudentController du bundle.

StudentController.php

<?php  
namespace AppBundle\Controller; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Response;  
use AppBundle\Entity\Student; 

class StudentController extends Controller { 
   /** 
      * @Route("/student/add") 
   */ 
   public function addAction() { 
      $stud = new Student(); 
      $stud->setName('Adam'); 
      $stud->setAddress('12 north street'); 
      $doct = $this->getDoctrine()->getManager();
      
      // tells Doctrine you want to save the Product 
      $doct->persist($stud);
      
      //executes the queries (i.e. the INSERT query) 
      $doct->flush(); 
      
      return new Response('Saved new student with id ' . $stud->getId()); 
   } 
}

Ici, nous avons accédé au gestionnaire de doctrine en utilisant la méthode getManager () via getDoctrine () du contrôleur de base, puis nous avons persisté l'objet actuel en utilisant la méthode persist () du gestionnaire de doctrine. persist() ajoute la commande à la file d'attente, mais la flush() fait le travail réel (persistance de l'objet étudiant).

Étape 10: Récupérer les objets de la base de données

Créez une fonction dans StudentController qui affichera les détails de l'étudiant.

StudentController.php

/** 
   * @Route("/student/display") 
*/ 
public function displayAction() { 
   $stud = $this->getDoctrine() 
   ->getRepository('AppBundle:Student') 
   ->findAll();
   return $this->render('student/display.html.twig', array('data' => $stud)); 
}

Étape 11: créer une vue

Créons une vue qui pointe vers l'action d'affichage. Allez dans le répertoire views et créez un fichier «display.html.twig». Ajoutez les modifications suivantes dans le fichier.

display.html.twig

<style> 
   .table { border-collapse: collapse; } 
   .table th, td { 
      border-bottom: 1px solid #ddd; 
      width: 250px; 
      text-align: left; 
      align: left; 
   } 
</style> 

<h2>Students database application!</h2>  
<table class = "table">  
   <tr>  
      <th>Name</th>  
      <th>Address</th>  
   </tr>  
   {% for x in data %} 
   <tr>  
      <td>{{ x.Name }}</td>   
      <td>{{ x.Address }}</td>   
   </tr>  
   {% endfor %} 
</table>

Vous pouvez obtenir le résultat en demandant l'URL «http: // localhost: 8000 / student / display» dans un navigateur.

Il produira la sortie suivante à l'écran -

Étape 12: mettre à jour un objet

Pour mettre à jour un objet dans StudentController, créez une action et ajoutez les modifications suivantes.

/** 
   * @Route("/student/update/{id}") 
*/ 
public function updateAction($id) { 
   $doct = $this->getDoctrine()->getManager(); 
   $stud = $doct->getRepository('AppBundle:Student')->find($id);  
   
   if (!$stud) { 
      throw $this->createNotFoundException( 
         'No student found for id '.$id 
      ); 
   } 
   $stud->setAddress('7 south street'); 
   $doct->flush(); 
   
   return new Response('Changes updated!'); 
}

Maintenant, demandez l'URL «http: // localhost: 8000 / Student / update / 1» et le résultat sera obtenu.

Il produira la sortie suivante à l'écran -

Étape 13: Supprimer un objet

La suppression d'un objet est similaire et nécessite un appel à la méthode remove () du gestionnaire d'entités (doctrine).

Cela peut être fait en utilisant la commande suivante.

/** 
   * @Route("/student/delete/{id}") 
*/ 
public function deleteAction($id) { 
   $doct = $this->getDoctrine()->getManager(); 
   $stud = $doct->getRepository('AppBundle:Student')->find($id);  
    
   if (!$stud) { 
      throw $this->createNotFoundException('No student found for id '.$id); 
   }  
    
   $doct->remove($stud); 
   $doct->flush();  
   
   return new Response('Record deleted!'); 
}