Desarrollo web Symfony2 parte 3

De WikiSalud
Saltar a: navegación, buscar

Véase Desarrollo_web_Symfony2_parte_2

Véase Configurar proyecto con Git

Contenido

Creación de Entidades con Doctrine

ORM

ORM (Object Relation Mapper) es una técnica de programación que permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de una base de datos pasan a ser clases y los registros se vuelven objetos.

ORM

Ventajas de utilizar un ORM:

  • Reutilización: permite llamar a los métodos de un objeto de datos desde distintas partes de la aplicación e incluso desde diferentes aplicaciones.
  • Encapsulación: encapsula la lógica de los datos lo que permite hacer cambios que afectan a toda la aplicación únicamente modificando una función.
  • Portabilidad: permite cambiar en mitad de un proyecto, por ejemplo, de una base de datos MySQL a una PostgreSQL sin ningún tipo de complicación. Esto es debido a que no utilizamos una sintaxis MySQL, PostgreSQL o SQLite para acceder a nuestro modelo, sino una sintaxis propia del ORM utilizado que es capaz de traducir a diferentes tipos de bases de datos.
  • Seguridad: implementan mecanismos de seguridad que protegen la aplicación de los ataques más comunes como SQL Injections.
  • Mantenimiento del código: realizar una modificación y mantener el código es una tarea sencilla.

Doctrine

Doctrine es un mapeador de objetos-relacional (ORM) escrito en PHP que proporciona una capa de persistencia para objetos PHP. Es una capa de abstracción que se sitúa justo encima de un Gestor de Base de Datos SGBD.

Cuando se trabaja con Doctrine, es necesario informar al motor interno de cual es el modelo de la aplicación, para ello se debe de hacer una ingeniería inversa de la base de datos existente o, si es una aplicación nueva, crear el modelo en la sintaxis específica que propona Doctrine y luego generar toda la base de datos.

Creación de entidades desde la base de datos

Con la base de datos ejemplo que se creo en el artículo anterior se crearán las entidades necesarias para realizar los mantenimientos necesarios. El esquema de la base de datos creada es el siguiente:

Modelo Lógico de BD Ejemplo

Por lo que se generará un diagrama de clases como se muestra en la siguiente imagen:

Diagrama de clase de ejemplo

Pasos para crear las entidades

  • Para crear las clases de la entidad en una base de datos existente es solicitar a Doctrine que examine la base de datos y genere los archivos de metadatos correspondientes. Los archivos de metadatos describen la clase entidad para generar tablas basándose en los campos. Para ello, desde consola en el directorio de Symfony del proyecto ejecutar como usuario normal lo siguiente:
php app/console doctrine:mapping:convert xml ./src/minsal/academicaAnBundle/Resources/config/doctrine/metadata/orm --from-database --force
Creación entidades

Al terminar de escribir la sentencia anterior presionar Enter y aparecerá lo que se muestra en la siguiente figura:

Creación entidades

La aplicación console de Symfony le pide a Doctrine que examine la estructura de la base de datos y genere los archivos XML de metadatos dentro del directorio src/minsal/academicaAnBundle/Resources/config/doctrine/metadata/orm del paquete, como se muestra en la siguiente figura:

Creación entidades
  • Una vez generados los archivos de metadatos, hay que pedir a Doctrine que importe el esquema y construya las clases relacionadas con la entidad. Con la siguiente sentencia se generan esas entidades:
php app/console doctrine:mapping:import minsalacademicaAnBundle annotation


Creación de clases

Doctrine generará la configuración de las entidades con annotation. Los otros tipos de configuraciones soportadas son php, yml y xml. Al ejecutar la sentencia, se creará dentro del paquete un directorio denominado Entity que contendrá todas las clases que representan las tablas de la base de datos. La estructura debe quedar como se muestra a continuación:

Directorio Entity

La sentencia anterior solo crea las clases junto con los atributos como se mostró en el diagrama de clases anterior y se puede observar en la siguiente imagen:

Entidad Asignatura
  • Ya se han creado las entidades pero se necesitan los métodos setter y getter que permiten acceder y definir la información que se tenga en el objeto. Para ello ejecutar en consola:
php app/console doctrine:generate:entities minsalacademicaAnBundle


Actualización entidades

Con las sentencias anterior las clases quedarán como se muestran en la imagen de la clase y el nuevo diagrama generado:

Entidad Asignatura Modificada


Diagrama de Clases Completo

Doctrine convierte todos los campos de la tabla a atributos privados y anotaciones de clase.

Explicación de la notación de Doctrine

Tipo de datos

Doctrine proporciona tipos de datos que son totalmente portátiles entre los gestores de base de datos. Estos tipos son:

Tipos de datos Doctrine
Doctrine SQL PHP
string VARCHAR string
integer INT integer
smallint SMALLINT integer
bigint BIGINT integer
boolean boolean boolean
decimal DECIMAL double
date DATETIME DateTime object
time TIME DateTime object
datetime DATETIME/TIMESTAMP DateTime object
text CLOB/TEXT string
object CLOB Objeto PHP usando serialize() y unserialize()
array CLOB Objeto PHP usando serialize() y unserialize()
float Float (Double Precision) double

Entidades

Cada entidad esta relacionada con una tabla. Para poder identificar a que tabla pertenece la entidad y en que paquete se encuentra; esto se puede apreciar en las siguientes líneas:

/**
 * minsal\academicaAnBundle\Entity\Asignatura
 *
 * @ORM\Table(name="asignatura")
 * @ORM\Entity
 */
  • minsal\academicaAnBundle\Entity\Asignatura: Indica que esta entidad se encuentra en un directorio llamado minsal en el paquete academicaAnBundle en el directorio 'Estity'.
  • @ORM\Table(name="asignatura"): indica el nombre que tiene la tabla en la base de datos.
  • @ORM\Entity: Indica que es una entidad.

Llaves Primarias

Todas las entidades requieren una llave primaria; dicho identificador es un campo marcado con la anotación @Id, además de su correspondiente anotación @Column que representa el nombre del campo en la base de datos. Un ejemplo es el que se presenta a continuación:

/**
 * @var integer $id
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="SEQUENCE")
 * @ORM\SequenceGenerator(sequenceName="asignatura_id_seq", allocationSize=1, initialValue=1)
 */
private $id;
  • @var integer $id: indica el nombre del atributo y el tipo de dato que representa.
  • @ORM\Column(name="id", type="integer", nullable=false):esta línea contiene la información del campo de la base de datos como es el nombre del campo, el tipo de dato y si es null o no.
  • @ORM\Id:le indica a Doctrine que es el ID de la tabla.
  • @ORM\GeneratedValue(strategy="SEQUENCE"): si el id es auto-numerico y que estrategia de auto-numeración se utiliza.
  • @ORM\SequenceGenerator(sequenceName="asignatura_id_seq", allocationSize=1, initialValue=1):esta línea se encuentra vinculada con la anterior; ya que indica el nombre de la secuencia a utilizar, el valor de inicio y el salto que se utilizará para su generación.
  • private $id; :nombre del atributo.

Los tipo de estrategias de secuencia son las siguientes:

  • AUTO (predeterminado): le indica a Doctrine que seleccione la mejor estrategia dependiendo del gestor de la base de datos. Las estrategias pueden ser IDENTITY para mysql, sqlite y sqlserver; SEQUENCE para Oracle y PostgreSQL.
  • SEQUENCE :Doctrine lo utiliza para generar el ID por medio de una secuencia. Esta estrategia no posee portabilidad total ya que solo es compatible con ORACLE y POSTGRES.
  • IDENTITY: Doctrine lo utiliza para los tipos de datos Identity. Esta estrategia no posee portabilidad total ya que solo es compatible con MySQL/SQLite (AUTO_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL).
  • NONE: Doctrine no realizará ninguna acción para generar el ID ya que el desarrollador será el encargado de realizar el código pertinente para su inserción.

Relaciones

La relación entre entidades tiene las siguientes características:

  • Cardinalidad: indica cuantas instancias pueden existir en cada lado de la relación.
  • Direccionalidad: define la forma en que se navega entre la entidades que mantienen una relación:
    • Unidireccional: si solo una entidad referencia a al otra.
    • Bidireccional: si cada entidad referencia a la otra.

Para el caso de la direccionalidad existen los conceptos de entidad propietaria o lado propietario y entidad inversa o lado inverso, la entidad propietaria de la relación determina la actualización de la relación en la base de datos, si tenemos dos referencias, una en cada lado de la asociación ambas referencias representan la misma asociación pero pueden cambiar independientemente de una a la otra, para esto Doctrine necesita conocer cuales cambios en memoria deben ser persistentes en la base de datos y cuales no, en este orden los cambios hechos en el lado inverso de la asociación son ignorados, y por esto se debe asegurar la correcta actualización de ambos lados de una asociación bidireccional. Los tipos de direccionalidad para Doctrine son los siguientes:

  • @OneToMany: indica que la entidad mantiene con este atributo una relación maestro-detalles.
  • @ManyToOne: en un atributo de una entidad detalle, indica que el atributo representa a la entidad maestra.
  • @OneToOne: atributo que representa entidad con la cual se mantiene relación 1-1.
  • @ManyToMany: atributo lista de entidades con las cuales se mantiene relación N-N.

Opcionalmente tenemos:

  • @JoinColumn: esta anotación permite definir la columna que se usará para hacer la relación.
  • @JoinTable: usado en el lado propietario de la relación y se usa para especificar los detalles de la tabla unión de la relación.
  • @OrderBy: para un atributo lista de detalles, indica el orden en que deben ser obtenidos sus miembros.

Para explicar mejor esta parte se tomará de ejemplo la siguiente relación:

Diagrama de Clases Asignatura-Estudiante

Si se observa en el diagrama, el atributo que trabaja como relación es idAsignaturaInscrita, el código de anotación que representa esta relación es la siguiente:

/**
 * @var Asignatura
 *
 * @ORM\ManyToOne(targetEntity="Asignatura")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id_asignatura_inscrita", referencedColumnName="id")
 * })
 */
 private $idAsignaturaInscrita;
  • @ORM\ManyToOne(targetEntity="Asignatura"):
  • @ORM\JoinColumn(name="id_asignatura_inscrita", referencedColumnName="id"):Se observa que en la Entidad Estudiante se tiene una campo denominado id_asignatura_inscrita y que hace referencia a la columna id de la tabla Asignatura.
Nota: para profundizar en esta parte de las relaciones visitar Doctrine2 Parte 4 Asociación 
o desde el sitio oficial Doctrine 2 ORM’s documentation

Métodos Setter y Getter

Cuando se tiene una relación, el método set recibe un objeto del tipo padre y lo almacena en el objeto hijo, como se observa en la siguiente imagen:

setIdAsignaturaInscrita---Estudiante

El método get retorna un objeto padre que se encuentra almacenado en el hijo:

getIdAsignaturaInscrita---Estudiante

Crear Base de datos desde entidades - Opcional

Si se tiene una aplicación en donde solo se conocen las entidades y no la base de datos. Doctrine a partir de esas entidades puede perfectamente crear la base de datos.

Para crear la base de datos solo el esquema sin la data del sistema. Se puede realizar de la siguiente manera:

  1. Crear la base desde consola como usuario postgres y crear el esquema con la aplicación console de symfony.
  2. Crear la base y el esquema desde la aplicación console de symfony.
Nota: Para la realización del ejemplo se deberá borrar la base de datos. Para ello abrir una consola como usuario postgres
y ejecutar la siguiente sentencia:
 dropdb nombreBase

Como se muestra en la siguiente imagen:

Borra base de datos

Crear la base desde consola como usuario postgres y crear el esquema con la aplicación console de symfony.

  • Para crear la base de datos con el usuario postgres se debe seguir los pasos explicados en Desarrollo_web_Symfony2_parte_2 en el apartado 2.1 Creación de usuario, base de datos y restauración de la base ejemplo. Sin restaurar la base.
  • Configurar el archivo parameters.yml del directorio app/config con la información acerca de la conexión de la base de datos como se muestra en la siguiente imagen.
Parameters.yml
  • Luego de configurar el archivo, abrir una consola como usuario normal y entrar al directorio NetBeansProjects/symfony/ y ejecutar:
 php app/console doctrine:schema:create
  • Al ejecutar la sentencia anterior aparecerá lo siguiente:
Resultado de la sentencia
  • Para verificar que el esquema de la base de datos se ha creado correctamente abrir una consola como usuario postgres y ejecutar:
 psql nombreBase

Luego de ejecutar la sentencia anterior y estar dentro de psql ejecutar:

 \d

Para seguir con el ejemplo el resultado que se obtiene después de ejecutar las dos sentencias anteriores es el siguiente.

Verificar desde psql
  • Si la verificación se desea realizar en modo gráfico. Abrir pgadmin3 y crear un servidor con los datos de la conexión. Al abrir esa nueva conexión podrá ver el esquema de la base de datos creada.
Verificar desde pgadmin3

Crear la base de datos y el esquema desde la aplicación console de symfony.

Aclaración: se debe tener en cuenta que para crear la base de datos desde la aplicación console, el usuario
que se utilice tenga permisos de crear base de datos. Como el usuario de este ejemplo no puede realizar esta acción 
se harán una serie de pasos para poder permitir la creación de bases de datos.
  • Abrir una consola como usuario postgres ejecutar psql para entrar a la aplicación nativa de postgres ejecutar:
 alter user user_db CREATEDB;

Presionar enter para ejecutar la consulta y con esto el usuario user_db podrá crear bases de datos.

Alter User
  • Abrir una consola como usuario normal entrar al directorio donde esta el proyecto y ejecutar la siguiente sentencia:
 php app/console doctrine:database:create

Luego de ejecutar la sentencia nos indica que la base de datos ha sido creada.

Crear base de datos desde console
  • Para verificar que la base de datos ha sido creada, abrir una consola como usuario postgres y ejecutar:
 psql -l
Verificación de la creación de la base
  • Como la base de datos ya fue creada, el usuario ya no necesita tener el rol de crear base de datos. Para quitar ese privilegio al usuario abrir una consola como usuario postgres ejecutar psql, ya dentro ejecutar:
 ALTER USER user_db NOCREATEDB;
Quitar Privilegio
  • Para cargar el esquema repetir la instrucciones del apartado anterior a partir de la ejecución de la siguiente sentencia:
 php app/console doctrine:schema:create

Restaurar el script original.

Para restaurar la base de datos original ejecutemos la siguiente sentencia como usuario postgres y estando en el directorio en donde esta el script ejemplo.sql

 dropdb symfony; createdb symfony -O user_db; psql -U user_db -d symfony -f ejemplo.sql

Dando como resultado:

Verificación de la creación de la base



3. Desarrollo_web_Symfony2_parte_4

Herramientas personales
Espacios de nombres

Variantes
Acciones
Navegación
Herramientas