Filtros en Hibernate
Normalmente las aplicaciones necesitan procesar en cada momento sólo un subconjunto de los datos disponibles.
Aunque se puede conseguir los mismo a través de otros métodos (normalmente consultas HSQL), los filtros nos permiten realizar esta tarea de una forma administrable, parametrizable y centralizada mediante los archivos de mapeo de hibernate.
A continuación vamos a ver un sencillo ejemplo de la creación y el uso de filtros. Para ello crearemos una sencilla BD que almacene datos de empleados, y luego crearemos un filtro para que filtre resultados por el género (masculino o femenino) de cada empleado.
Un ejemplo
Script de creación de la BD MySql.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
-- Creamos un esquema para el ejemplo CREATE SCHEMA IF NOT EXISTS db_test; -- Establecemos el esquema como predeterminado USE db_test; -- Creamos la tabla CREATE TABLE IF NOT EXISTS empleados ( usuario VARCHAR(25) NOT NULL, nombre VARCHAR(128), genero VARCHAR(1), PRIMARY KEY (usuario) ) ENGINE=InnoDB CHARSET=utf8 collate=utf8_general_ci; -- Añadimos unos registros de prueba eliminadolos previamente si existiesen DELETE FROM empleados WHERE usuario IN ('user1', 'user2', 'user3', 'user4', 'user5'); INSERT INTO empleados (usuario, nombre, genero) VALUES ('user1', 'Andres Sánchez Sánchez', 'M'), ('user2', 'Carolina Pérez Gómez', 'F'), ('user3', 'Carlos García Pérez', 'M'), ('user4', 'Ana Sevilla Luna', 'F'); |
A continuación vemos la clave Empleado.
Empleado.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package com.autentia.tutoriales.hibernate.filters.dao; /** * @author Carlos García. Autentia. * @see http://www.mobiletest.es */ public class Empleado { /** * Identificador del empleado dentro del sistema */ private String usuario; /** * Nombre completo del empleado */ private String nombre; /** * Género: * M=Masculino, F=Femenino */ private String genero; public String getUsuario() { return usuario; } public void setUsuario(String usuario) { this.usuario = usuario; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getGenero() { return genero; } public void setGenero(String genero) { this.genero = genero; } /* * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { try { return ((Empleado) obj).usuario.equals(this.usuario); } catch (Exception ex) { return false; } } } |
A continuación mostramos una aplicación de escritorio autocomentada en el que se hace uso del filtro (líneas 46, 47 y 53).
SimpleFilterApp.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package com.autentia.tutoriales.hibernate.filters; import java.util.Iterator; import java.util.List; import org.hibernate.*; import org.hibernate.cfg.Configuration; import com.autentia.tutoriales.hibernate.filters.dao.Empleado; /** * Aplicación de escritorio de ejemplo del uso de filtros * @author Carlos García. Autentia. * @see http://www.mobiletest.es */ public class SimpleFilterApp { /** * Muestra los empleados. */ private static void showEmployees(Session session){ Query query = session.createQuery("from Empleado"); List<Empleado> empleados = query.list(); Iterator<Empleado> ite = empleados.iterator(); Empleado emp = null; while (ite.hasNext()){ emp = ite.next(); System.out.println(emp.getNombre()); } } /** * Punto de entrada de la aplicación de ejemplo */ public static void main(String[] args) { Configuration configuration = new Configuration().configure(); SessionFactory factory = configuration.buildSessionFactory(); Session session = factory.openSession(); System.out.println("Mostramos TODOS los usuarios:"); showEmployees(session); // Activamos el filtro para mostrar sólo a los empleados mujeres Filter filtro = session.enableFilter("filtroGenero"); filtro.setParameter("generoParam", "F"); System.out.println("Mostramos sólo las mujeres:"); showEmployees(session); // Desactivamos el filtro session.disableFilter("filtroGenero"); session.close(); } } |
A continuación, mostramos el fichero de configuración de Hibernate:
hibernate.cfg.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db_test</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">usuario_bd</property> <property name="hibernate.connection.password">clave_acceso</property> <property name="hibernate.connection.pool_size">0</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <mapping resource="Empleado.hbm.xml"/> </session-factory> </hibernate-configuration> |
A continuación, mostramos el fichero de mapeo de la clase Empleado:
Empleado.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.autentia.tutoriales.hibernate.filters.dao.Empleado" table="empleados" > <id name="usuario" type="string"> <generator class="assigned"/> </id> <property name="nombre" type="string" length="128"/> <property name="genero" type="string" length="1"/> <filter name="filtroGenero" condition=":generoParam = genero"></filter> </class> <filter-def name="filtroGenero"> <filter-param name="generoParam" type="string"/> </filter-def> </hibernate-mapping> |
Sobran comentarios, verdad?? se ve claramente como se definen el filtro (lineas 16, 17 y 18) y como se asocian a las clases (linea 13).
Conclusiones
Aunque los filtros tienen limitaciones, especialmente que no se pueden crear filtros en tiempo de ejecución.
En ciertas ocasiones pueden ser una solución a tener en cuenta, pues nos pueden evitar tener que reescribir las consultas de acceso a los datos
que aparecen a lo largo de la aplicación, estableciendo simplemente los filtros necesarios cuando se crea la sesión.
Un saludo.
Carlos García. Creador de MobileTest.