Volvemos con la segunda parte de “Conociendo un ORM”, continuando el desarrollo que dejamos a medias con Hibernate. Una vez realizada la configuración, los modelos y sus mapeos correspondientes solo nos queda apoyarnos de toda la configuración para poder obtener, insertar, editar y eliminar los datos de la aplicación haciéndolos persistir en la base de datos.
Un buen hábito de desarrollo es construir una clase HibernateUtil que se apoye en el patrón Singleton. El objetivo de emplear este patrón es el de garantizar que una clase solo tenga una instancia en la aplicación, y proporcionar un único punto de acceso global a ella, Hibernate trabaja con sesiones y genera una instancia de la base de datos para trabajar con ella, por lo tanto es lógico y un buen hábito de trabajo cuando se trabaja con éste framework de persistencia crear esta clase que proporciona un único punto de acceso a dicha instancia, evitando crear una sesión distinta desde distintos puntos de la aplicación que finalmente nos puede llevar a generación de errores y consumo innecesario de memoria.
Para ello se desarrolla la clase “HibernateUtil” en la cual declaramos un atributo “static” del tipo “SessionFactory” asegurándonos de que solo existe una instancia. Además este atributo se define como final para que no pueda ser modificado ni alterado por ningún cliente que lo referencie. Gracias al patrón Singleton obtenemos un acceso controlado de la sesión, las clases que deseen una referencia a la sesión única la obtendrán llamando al método estático getSessionFactory() de la clase:
public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { // Create the SessionFactory from hibernate.cfg.xml return new AnnotationConfiguration().configure() .buildSessionFactory(); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
A continuación debemos definir unas clases manejadoras que nos proporcione las operaciones CRUD básicas. Aquí podemos ver como cada función obtiene la Sesión correspondiente através de Hibernate Util, y esta sesión nos proporciona los métodos básicos para las operaciones CRUD (Crear, Obtener, Actualizar y Eliminar)(Create, Read, Update and Delete). Es importante destacar que para realizar consultas mas complejas Hibernate proporciona ciertas herramientas como los Criteria o un lenguaje especial llamado HQL. Aquí muestro las funciones básicas de los Manager:
public class ClienteManager { public Cliente add(Cliente cliente) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(cliente); session.getTransaction().commit(); return cliente; } public Cliente update(Cliente user) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.update(user); session.getTransaction().commit(); return user; } @SuppressWarnings("rawtypes") public Cliente getClienteById(String id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Criteria crit = session.createCriteria(Cliente.class).add(Restrictions.eq("id",id)); List result=crit.list(); session.getTransaction().commit(); if (result.isEmpty()) return null; else return (Cliente)result.get(0); } public Cliente delete(Long id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Cliente contact = (Cliente) session.load(Cliente.class, id); if(null != contact) { session.delete(contact); } session.getTransaction().commit(); return contact; } @SuppressWarnings("unchecked") public List list() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); List contacts = null; try { contacts = (List)session.createQuery("from Cliente").list(); } catch (HibernateException e) { e.printStackTrace(); session.getTransaction().rollback(); } session.getTransaction().commit(); return contacts; } } public class PedidosManager { public Pedido add(Pedido pedido) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(pedido); session.getTransaction().commit(); return pedido; } public List getPedidoByUserId(int id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Criteria crit = session.createCriteria(Pedido.class).add(Restrictions.like("cliente_id", id)); List result=crit.list(); session.getTransaction().commit(); return result; } public Pedido getPedidoById(int id) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); Criteria crit = session.createCriteria(Pedido.class).add(Restrictions.like("id", id)); List result=crit.list(); session.getTransaction().commit(); return (Pedido) result.get(0); } @SuppressWarnings("unchecked") public List list() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); List pedidos = null; try { pedidos = (List) session.createCriteria(Pedido.class).list(); } catch (HibernateException e) { e.printStackTrace(); session.getTransaction().rollback(); } session.getTransaction().commit(); return pedidos; } public Pedido update(Pedido pedido) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.merge(pedido); session.getTransaction().commit(); return pedido; } }
Procedamos a ver como se emplea esta arquitectura de clases. Este ejemplo sencillo crea un nuevo objeto de la clase Cliente, estableciendo con sus métodos set los distintos atributos de este y finalmente pasándo el objeto al Manager para que se encargue de persistirlo en la base de datos:
Cliente cliente = new Cliente(); cliente.setApellidos(getApellido()); cliente.setNombre(getNombre()); cliente.setDomicilio(getDomicilio()); cliente = clienteManager.add(cliente);
Espero que hayáis disfrutado con estos pequeños ejemplos. Volveré a tratar el tema de los ORM con más profundidad analizando alguna otra herramienta o describiendo características más avanzadas de Hibernate. Aún así os comparto la documentación oficial de la versión 3.5.7 que viene muy bien explicado y con ejemplos
[googleplusauthor]