Symfony - Doctrine ORM

En el framework web Symfony, el modelo juega un papel importante. Son las entidades comerciales. Los proporcionan los clientes o se obtienen de la base de datos back-end, se manipulan de acuerdo con las reglas comerciales y se conservan en la base de datos. Son los datos presentados por Views. Aprendamos sobre los modelos y cómo interactúan con el sistema de back-end en este capítulo.

Modelo de base de datos

Necesitamos mapear nuestros modelos a los elementos de la base de datos relacional de back-end para recuperar y conservar los modelos de manera segura y eficiente. Este mapeo se puede hacer con una herramienta de mapeo relacional de objetos (ORM). Symfony proporciona un paquete separado,DoctrineBundle, que integra Symfony con la herramienta ORM de base de datos PHP de terceros, Doctrine.

Doctrina ORM

De forma predeterminada, el marco de Symfony no proporciona ningún componente para trabajar con bases de datos. Pero, se integra estrechamente conDoctrine ORM. Doctrine contiene varias bibliotecas PHP que se utilizan para el almacenamiento de bases de datos y la asignación de objetos.

El siguiente ejemplo le ayudará a comprender cómo funciona Doctrine, cómo configurar una base de datos y cómo guardar y recuperar los datos.

Ejemplo de ORM de Doctrine

En este ejemplo, primero configuraremos la base de datos y crearemos un objeto Student, luego realizaremos algunas operaciones en él.

Para hacer esto, debemos seguir los siguientes pasos.

Paso 1: crea una aplicación Symfony

Crea una aplicación Symfony, dbsample usando el siguiente comando.

symfony new dbsample

Paso 2: configurar una base de datos

Generalmente, la información de la base de datos se configura en el archivo “app / config / parameters.yml”.

Abra el archivo y agregue los siguientes cambios.

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

Ahora, Doctrine ORM puede conectarse a la base de datos.

Paso 3: crear una base de datos

Emita el siguiente comando para generar la base de datos "estudiantesdb". Este paso se usa para vincular la base de datos en Doctrine ORM.

php bin/console doctrine:database:create

Después de ejecutar el comando, genera automáticamente una base de datos "estudiantesdb" vacía. Puede ver la siguiente respuesta en su pantalla.

Created database `studentsdb` for connection named default

Paso 4: Información del mapa

La información de mapeo no es más que "metadatos", es una colección de reglas que informa a Doctrine ORM exactamente cómo la clase Student y sus propiedades se mapean en una tabla de base de datos específica.

Bueno, estos metadatos se pueden especificar en varios formatos diferentes, incluidos YAML, XML o puede pasar directamente la clase de estudiante mediante anotaciones. Se define como sigue.

Student.php

Agregue los siguientes cambios en el archivo.

<?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; 
}

Aquí, el nombre de la tabla es opcional. Si no se especifica el nombre de la tabla, se determinará automáticamente en función del nombre de la clase de entidad.

Paso 5: vincular una entidad

Doctrine crea clases de entidad simples para ti. Te ayuda a construir cualquier entidad.

Emita el siguiente comando para generar una entidad.

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

Luego verá el siguiente resultado y la entidad se actualizará.

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; 
   } 
}

Paso 6: Validación del mapa

Después de crear las entidades, debe validar las asignaciones con el siguiente comando.

php bin/console doctrine:schema:validate

Producirá el siguiente resultado:

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

Como no hemos creado la tabla de estudiantes, la entidad no está sincronizada. Creemos la tabla de estudiantes usando el comando de Symfony en el siguiente paso.

Paso 7: crear un esquema

Doctrine puede crear automáticamente todas las tablas de la base de datos necesarias para la entidad Student. Esto se puede hacer usando el siguiente comando.

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

Después de ejecutar el comando, puede ver la siguiente respuesta.

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

Este comando compara el aspecto que debería tener su base de datos con su aspecto real y ejecuta las sentencias SQL necesarias para actualizar el esquema de la base de datos a donde debería estar.

Ahora, vuelva a validar el esquema con el siguiente comando.

php bin/console doctrine:schema:validate

Producirá el siguiente resultado:

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

Paso 8: Getter y setter

Como se ve en la sección Vincular una entidad, el siguiente comando genera todos los captadores y definidores para la clase Student.

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

Paso 9: Conservar objetos en la base de datos

Ahora, hemos mapeado la entidad Student a su tabla Student correspondiente. Ahora deberíamos poder conservar los objetos Student en la base de datos. Agregue el siguiente método al StudentController del paquete.

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()); 
   } 
}

Aquí, accedimos al administrador de doctrina usando el método getManager () a través de getDoctrine () del controlador base y luego persistimos el objeto actual usando el método persist () del administrador de doctrina. persist() El método agrega el comando a la cola, pero el flush() El método hace el trabajo real (conservando el objeto del estudiante).

Paso 10: recuperar objetos de la base de datos

Cree una función en StudentController que muestre los detalles del estudiante.

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)); 
}

Paso 11: crear una vista

Creemos una vista que apunte a mostrar acción. Vaya al directorio de vistas y cree un archivo "display.html.twig". Agregue los siguientes cambios en el archivo.

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>

Puede obtener el resultado solicitando la URL “http: // localhost: 8000 / student / display” en un navegador.

Producirá el siguiente resultado en pantalla:

Paso 12: actualizar un objeto

Para actualizar un objeto en StudentController, cree una acción y agregue los siguientes cambios.

/** 
   * @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!'); 
}

Ahora, solicite la URL “http: // localhost: 8000 / Student / update / 1” y producirá el siguiente resultado.

Producirá el siguiente resultado en pantalla:

Paso 13: eliminar un objeto

Eliminar un objeto es similar y requiere una llamada al método remove () del administrador de la entidad (doctrine).

Esto se puede hacer usando el siguiente comando.

/** 
   * @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!'); 
}