Symfony - Doctrine ORM

No framework web Symfony, o modelo desempenha um papel importante. Eles são as entidades comerciais. Eles são fornecidos pelos clientes ou buscados no banco de dados de back-end, manipulados de acordo com as regras de negócios e persistentes no banco de dados. Eles são os dados apresentados por Views. Vamos aprender sobre os modelos e como eles interagem com o sistema back-end neste capítulo.

Modelo de Banco de Dados

Precisamos mapear nossos modelos para os itens do banco de dados relacional de back-end para buscar e manter os modelos com segurança e eficiência. Esse mapeamento pode ser feito com uma ferramenta Object Relational Mapping (ORM). Symfony fornece um pacote separado,DoctrineBundle, que integra Symfony com ferramenta ORM de banco de dados PHP de terceiros, Doctrine.

Doutrina ORM

Por padrão, o framework Symfony não fornece nenhum componente para trabalhar com bancos de dados. Mas, ele se integra perfeitamente comDoctrine ORM. Doctrine contém várias bibliotecas PHP usadas para armazenamento de banco de dados e mapeamento de objetos.

O exemplo a seguir irá ajudá-lo a entender como o Doctrine funciona, como configurar um banco de dados e como salvar e recuperar os dados.

Exemplo de Doutrina ORM

Neste exemplo, primeiro configuraremos o banco de dados e criaremos um objeto Aluno e, em seguida, realizaremos algumas operações nele.

Para fazer isso, precisamos seguir as etapas a seguir.

Etapa 1: Criar um aplicativo Symfony

Crie um aplicativo Symfony, dbsample usando o seguinte comando.

symfony new dbsample

Etapa 2: configurar um banco de dados

Geralmente, as informações do banco de dados são configuradas no arquivo “app / config / parameters.yml”.

Abra o arquivo e adicione as seguintes alterações.

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

Agora, Doctrine ORM pode se conectar ao banco de dados.

Etapa 3: Criar um banco de dados

Emita o seguinte comando para gerar o banco de dados “studentsdb”. Esta etapa é usada para ligar o banco de dados no Doctrine ORM.

php bin/console doctrine:database:create

Depois de executar o comando, ele gera automaticamente um banco de dados “studentsdb” vazio. Você pode ver a seguinte resposta em sua tela.

Created database `studentsdb` for connection named default

Etapa 4: informações do mapa

Mapping information nada mais é do que "metadados". É uma coleção de regras que informa ao Doctrine ORM exatamente como a classe Student e suas propriedades são mapeadas para uma tabela de banco de dados específica.

Bem, esses metadados podem ser especificados em vários formatos diferentes, incluindo YAML, XML ou você pode passar diretamente na aula do aluno usando anotações. É definido como segue.

Student.php

Adicione as seguintes alterações no arquivo.

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

Aqui, o nome da tabela é opcional. Se o nome da tabela não for especificado, ele será determinado automaticamente com base no nome da classe de entidade.

Etapa 5: vincular uma entidade

O Doctrine cria classes de entidade simples para você. Ajuda você a construir qualquer entidade.

Emita o seguinte comando para gerar uma entidade.

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

Então você verá o seguinte resultado e a entidade será atualizada.

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

Etapa 6: Validação do mapa

Depois de criar entidades, você deve validar os mapeamentos usando o seguinte comando.

php bin/console doctrine:schema:validate

Isso produzirá o seguinte resultado -

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

Como não criamos a tabela de alunos, a entidade está fora de sincronia. Vamos criar a tabela de alunos usando o comando Symfony na próxima etapa.

Etapa 7: criar um esquema

O Doctrine pode criar automaticamente todas as tabelas de banco de dados necessárias para a entidade Aluno. Isso pode ser feito usando o seguinte comando.

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

Depois de executar o comando, você pode ver a seguinte resposta.

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

Este comando compara a aparência do banco de dados com a aparência real e executa as instruções SQL necessárias para atualizar o esquema do banco de dados para onde deveria estar.

Agora, valide novamente o esquema usando o seguinte comando.

php bin/console doctrine:schema:validate

Isso produzirá o seguinte resultado -

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

Etapa 8: Getter e setter

Conforme visto na seção Vincular uma entidade, o comando a seguir gera todos os getters e setters para a classe Aluno.

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

Etapa 9: Persistir Objetos no Banco de Dados

Agora, mapeamos a entidade Student para sua tabela Student correspondente. Agora devemos ser capazes de persistir os objetos de Aluno no banco de dados. Adicione o seguinte método ao StudentController do pacote.

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

Aqui, acessamos o gerenciador de doutrina usando o método getManager () por meio de getDoctrine () do controlador de base e então persistimos o objeto atual usando o método persist () do gerenciador de doutrina. persist() método adiciona o comando à fila, mas o flush() método faz o trabalho real (persistindo o objeto de aluno).

Etapa 10: Buscar objetos do banco de dados

Crie uma função em StudentController que exibirá os detalhes do aluno.

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

Etapa 11: criar uma visualização

Vamos criar uma visão que aponta para a ação de exibição. Vá para o diretório de visualizações e crie um arquivo “display.html.twig”. Adicione as seguintes alterações no arquivo.

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>

Você pode obter o resultado solicitando a URL “http: // localhost: 8000 / student / display” em um navegador.

Ele produzirá a seguinte saída na tela -

Etapa 12: Atualizar um objeto

Para atualizar um objeto em StudentController, crie uma ação e adicione as seguintes alterações.

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

Agora, solicite a URL “http: // localhost: 8000 / Student / update / 1” e produzirá o seguinte resultado.

Ele produzirá a seguinte saída na tela -

Etapa 13: Excluir um objeto

Excluir um objeto é semelhante e requer uma chamada ao método remove () do gerenciador de entidade (doutrina).

Isso pode ser feito usando o seguinte 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!'); 
}