El componente encargado de gestionar el modelo en Symfony es la capa ORM (Object Relational Mapping, o Mapeo de Objetos a Bases de Datos), encargada del Acceso y Modificación de los datos almacenados en la Base de Datos mediante el uso de objetos. Esta capa de abstracción esta basada en el proyecto Propel. Basicamente, podemos acceder y modificar datos de una basededatos de forma sencilla utilizando la logica objeto y no los clasicos Update y Select de sql.
ORM es la interfaz encarga de traducir la lógica de Orientación a Objetos (de los objetos) a la lógica relacional (de las tablas). ORM permite que nuestras aplicaciones web sean independientes del gestor de la base de datos y por tanto poder migrar o portar nuestra aplicación a otra base de datos sin cambiar el código de las clases del modelo Se utilizan objetos en vez de registros y clases en vez de tablas. El programador de Symfony usa las clases, objetos, y crea nuevos métodos para acceder a los datos de la base de datos.
Qué es ORM
Qué es ORM
objeto registro Clase tabla propiedad campo Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]EL MODELO
EL MODELO
El esquema de la Base de la Base de Datos
El esquema de la Base de la Base de Datos
Fichero
tienda.sql
almacenado en
data/sql
Tabla Categoría, Editores y Libros
Un libro pertenece a una categoría y a un editor
Estructura y Datos
Claves foráneas en Libros: categoriaid, editorid (muy importante para el modelo. Se crea
un método en la clase Libros que nos devuelve el objeto Editor y Categoría con el que
está relacionado)
Crear la Base de Datos librería en mysql: mysql:> create database librería
Volcado de datos: # mysql u root p pass librería < data/sql/tienda.sql
EL MODELO
EL MODELO
El fichero Databases.yml
El fichero Databases.yml
En este fichero se establece los parámetros de conexión con la base de datos, indicando
el gestor de la base de datos, el nombre de la base de datos, el nombre del host, el
usuario, contraseña, la cadena de conexión etc
Se encuentra en el directorio config del proyecto
Está en formato yaml
Se puede configurar conexiones a bases de datos para diferentes entornos: dev, prod,
test, all ...
Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]
EL MODELO
EL MODELO
Generación del Esquema
Generación del Esquema
Una vez tenemos nuestra estructura de base de datos almacenada, debemos de generar el esquema de la base de datos. Este esquema es simplemente una traducción de la estructura sql de la base de datos en el fichero schema.yml, del directorio config del proyecto, en formato yaml. Contiene la estructura de las tablas en formato yml.
Define tablas, campos, tipos, atributos avanzados de los campos, claves foráneas, índices, columnas vacias ...
La instrucción symfony propelbuildschema genera el fichero schema.yml en el directorio config, necesario para la generación del modelo. (necesario)
Existe la posibilidad de definir el esquema en formato xml, algo más expresivo que yml pero también más pesado.
La instrucción symfony propelbuildsql genera el fichero lib.model.schema.sql en el directorio data/sql a partir de la estructura sql de la base de datos. (Opcional). En nuestro caso es tienda.sql.
La página 153 y 169 del capítulo 8 de libro de Symfony habla de los esquemas.
EL MODELO
Generación del Modelo
Generación del Modelo
Parte del fichero .sql en data/sql del proyecto
La instrucción symfony propelbuildmodel genera el esquema de clases y objetos a partir del schema Genera una clase Base y una clase tipo Peer por cada tabla existente en la estructura sq. Pe: Para la tabla libros se genera: BaseLibros.php, BaseLibrosPeer.php (generadas siempre, se borran) Libros.php y LibrosPeer.php (heredan, no se borran, son modificables)
Se generan:
lib/model/map: CategoriasMapBuilder.php, EditoresMapBuilder.php, LibrosMapBuilder.php lib/model/om: BaseCategorias.php, BaseCategoriasPeer.php, BaseEditores.php, BaseEditoresPeer.php, BaseLibros.php, BaseLibrosPeer.php. Clases de Base (acceso a campos del registro actual) y tipo Clase tipo Peer (para acceso a los registros de una tabla). Son clases GENERADAS cada vez que se genera el modelo, Y NUNCA DEBEN DE SER MODIFICABLES por el usuario lib/model: Clases Libros.php, LibrosPeer.php, Editores.php, EditoresPeer.php, Categorias.php, CategoriasPeer.php, que heredan de las clases de Base y tipo Peer correspondiente. No se borran al generar de nuevo el modelo y deben ser MODIFICADAS Y EXTENDIDAS por el usuario.BaseLibros Libros BaseLibrosPeer LibrosPeer herencia Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]
EL MODELO
EL MODELO
Generación del Modelo
Generación del Modelo
La clase (tipo Base) BaseLibros.php contiene:
Métodos get/set para acceso a los campos del registro actual, como getNombreLibro() Métodos para borrar (delete()) y almacenar (save()) un objeto (o registro según se vea) Métodos de acceso a campos getByName() y getByPosition() Métodos de acceso a la clave primaria de la tabla getPrimaryKey() Métodos de acceso a clases relacionadas. Por ejemplo al objeto Categorias y Editores con el que está relacionado el libro, getCategorias() y getEditores(). De modo que podríamos hacer cosas como: $libros>getEditorId() “Obtenemos el id del editor del libro” $libros>getEditores()>getNombreEditorial() “Nombre de la editorial del libro” $libros>getCategorias()>getNombreCategoria() “Nombre de la categoria del libro” Nota: Esto es muy útil y es posible gracias al establecimiento de las claves foráneas en la tabla libro”La clase (tipo Peer) BaseLibrosPeer.php contiene:
Métodos estáticos para obtener y realizar acciones para obtener los objetos (registros de las tablas). Sus métodos devuelven un objeto o una colección de objetos Métodos doCount(), doSelect(), doSelectJoinX(), doUpdate(), doInsert(), doDelete() Sus métodos se invocan de forma estática. No se pueden crear objetos de las clases Peer.EL MODELO
EL MODELO
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Desarrollo de Aplicaciones web con el Framework Symfony y AjaxPodemos añadir nuevos métodos al modelo o redefinir los ya existentes. Siempre modificaremos las clases X y XPeer, nunca BaseX y BaseXPeer
$this para invocar a los métodos del objeto actual, self:: para invocar a los métodos estáticos de la clase actual, parent:: invoca a métodos del padre. Se utiliza variable = new Clase(), cuando desde un objeto hacemos clientela con otra clase. $libro = new Libro(), nos devuelve un libro. $libros = LibrosPeer::metodo() devuelve un conjunto de objetos que son resultado de aplicar metodo() sobre el onjetoLibrosPeer o en su defecto BaseLibrosPeer.
EL MODELO
EL MODELO
RetrieveByPk() permite tantos parámetros como campos tenga la clave primaria. Retorna el objeto cuya clave principal coincide con la pk del argumento. RetrieveByPks() espera como argumento un array de claves primarias. Devuelve un array de objetos. Código codificado en alguna Acción de algún módulo de la capa del CONTROLADOR Código codificado en alguna Acción de algún módulo de la capa del CONTROLADOR $libro = LibrosPeer::retrieveByPk(12), nos devuelve el libro cuyo libro_id es 12. Pensad en la select correspondiente. Iden con retrieveByPks(). $editor = EditorPeer::retrieveByPk ($libro>getEditorid()). Objeto editor con el que esta relacionado el ojeto $libro
Extender y Modificar el Modelo
Extender y Modificar el Modelo
RetrieveByPk y retrieveByPksEL MODELO
EL MODELO
El método doSelect( Criteria ) equivale al Select de Sql.:
doSelect usa como parámetro el objeto Criteria y es un método de la clase Peer. LibrosPeer::doSelect(), obtiene un array de objetos de tipo Libro.
optimiza el código SQL
Todos los parámetros pasados en Criteria se escapan antes de insertarlos en SQL
doSelect() Devuelve un array de objetos y no un resulset (array de registros en una matriz).
El ORM crea y rellena de forma automática los objetos en función del result set, proceso de hydrating. Por cada registro se crea en memoria una estructura que es el objeto correspondiente. doSelect(): Obtiene un array de objetos. doCount(): obtiene un valor que es el número de registros que cumplen las condiciones de criteria doSelecOne(): devuelve un único objeto, no array de objetos. Útil cuando la select devuelve un registro doSelectRS(): devuelve un recordset o resulset. Pe. “Nombre y apellidos de alumnos de 3 de la eso”. doInsert(), doUpdate(), doDelete(): Operadores: LIKE: Criteria::LIKE IN, NOT_IN: Criteria::IN, Criteria::NOT_IN Is Null, Is Not Null: Criteria::ISNULL, Criteria::ISNOTNULL DoSelect, doSelectRS, y Criteria
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]EL MODELO
EL MODELO
El objeto criteria se emplea para codificar las condiciones o los filtros en una consulta select. Se debe de rellenar antes de invocar a doSelect(). Si criteria es vacio, se devuelven todos los objetos de la clase. $c = new Criteria(); $libros = LibrosPeer::doSelect($c) Consultar la página 160 del manual de symfony Características o parámetros: addSelectColumn(): añade la selección de columna add(): añade los filtros addJoin(): realiza un join entre tablas addDescendingOrderByColumn(): orden descendente de un campo addGroupByColumn(): agrupación o group by setLimit(), setOffset(): extraer un número de registros desde una posición Criteria
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Crear criteria Rellenar criteria doSelectRS() doSelec() recorridoEL MODELO
EL MODELO
Idea del Proceso con doSelectRS() Sacar Libro_id, precio, nombre editorial, nombre categoria cuya entrega>2 $c = new Criteria(); // creamos criteria (paso 1) // seleccionamos las columnas: addSelectColumn() //lo rellenamos (paso 2) $c>addSelectColumn(LibrosPeer::LIBRO_ID); $c>addSelectColumn(LibrosPeer::PRECIO); $c>addSelectColumn(EditoresPeer::NOMBRE_EDITORIAL); $c>addSelectColumn(CategoriasPeer::NOMBRE_CATEGORIA); //Hacemos Joins: addJoin() $c>addJoin(LibrosPeer::EDITORID,EditoresPeer::EDITORID); $c>addJoin(LibrosPeer::CATEGORIAID,CategoriasPeer::CATEGORIAID); //Hacemos los filtros: add() $c>add(LibrosPeer::ENTREGA,2, Criteria::GREATHER_THAN) $c>addDescendingOrderByColumn(EditoresPeer::NOMBRE_EDITORIAL); //Hacemos la selec: doSelectRS() y obtenemos el resulset (paso 3) $libros = LibrosPeer::doSelectRS($c); //Recorremos el recordset. // lo recorremos (paso 4) while ($libros>next()) { $libros['libro_id'] = ...); }
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]EL MODELO
EL MODELO
Idea del Proceso con doSelect()
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Desarrollo de Aplicaciones web 1. Creamos un objeto tipo Criteria(): $criteros = new Criteria(); 2. Añadimos condiciones y criterios: $criterios>add(LibrosPeer::LIBRO_ID, 12, Criteria::GREATER_EQUAL) “Libro_id>=12” ... 3. Realizamos el doSelect y obtemos los registros o el array de objetos libros $libros = LibrosPeer::doSelect ($cirterios) 4. Recorremos el array de objetos libros, obtenemos un libro y accedemos a sus atributos foreach ($libros as $libro) { $total = $total + $libro>getPrecio(); $editorial[] = $libro>getEditores()>getNombreEditorial(); }EL MODELO
EL MODELO
Ejemplos: El precio del libro es con iva al 16%. Redefinir el método getPrecio() en Libros.php (Redefinir) public function getTotal($editorial) { $total = 0; $c = new Criteria(); $libros = self::doSelect($c); //LibrosPeer::doSelect($c); foreach ($libros as $libro){ if ($libros>getEditores()>getNombreEditorial() == $editorial) $total = $total + $libro>getPrecio(); } return $total; //se invoca con getTotal('Anaya') } Calcular el total de los precios de los libros de la editorial Anaya en LibrosPeer
public function getTotal($editorial) { $total = 0; $c = new Criteria(); $libros = self::doSelect($c); //LibrosPeer::doSelect($c); foreach ($libros as $libro){ if ($libros>getEditores()>getNombreEditorial() == $editorial) $total = $total + $libro>getPrecio(); } return $total; //se invoca con getTotal('Anaya') }
EL MODELO
EL MODELO
Extender y Modificar el Modelo
Extender y Modificar el Modelo
Desarrollo de Aplicaciones web con el Framework Symfony y Ajax José Antonio Morgado Berruezo José Antonio Morgado Berruezo [email protected] [email protected]