unidades:07_arquitectura:03_dao
Diferencias
Muestra las diferencias entre dos versiones de la página.
— | unidades:07_arquitectura:03_dao [2023/04/07 21:26] (actual) – creado - editor externo 127.0.0.1 | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
+ | ====== DAO ====== | ||
+ | Pasemos ahora a ver cómo implementar el patrón [[patrones: | ||
+ | El mayor problema del patrón [[patrones: | ||
+ | |||
+ | |||
+ | ===== Los interfaces ===== | ||
+ | El siguiente diagrama UML explica los interfaces '' | ||
+ | |||
+ | <uml> | ||
+ | note "Clase Generica con Tipos T e ID" as N1 | ||
+ | class GenericDAO << | ||
+ | GenericDAO : T create() | ||
+ | GenericDAO : void saveOrUpdate(T entity) | ||
+ | GenericDAO : T get(ID id) | ||
+ | GenericDAO : void delete(ID id) | ||
+ | GenericDAO : List< | ||
+ | |||
+ | N1 .. GenericDAO | ||
+ | |||
+ | class ProfesorDAO << | ||
+ | class UsuarioDAO << | ||
+ | |||
+ | GenericDAO <|.. ProfesorDAO | ||
+ | GenericDAO <|.. UsuarioDAO | ||
+ | |||
+ | </ | ||
+ | |||
+ | Como podemos ver, los objetos DAO de Profesor y Usuario son realmente los interfaces '' | ||
+ | |||
+ | El código Java relativo a los 3 interfaces es el siguiente: | ||
+ | <code java 1 | GenericDAO.java > | ||
+ | public interface GenericDAO< | ||
+ | T create() throws BussinessException; | ||
+ | void saveOrUpdate(T entity) throws BussinessException; | ||
+ | T get(ID id) throws BussinessException; | ||
+ | void delete(ID id) throws BussinessException; | ||
+ | List< | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java 1 | ProfesorDAO.java > | ||
+ | public interface ProfesorDAO extends GenericDAO< | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java 1 | UsuarioDAO.java > | ||
+ | public interface UsuarioDAO extends GenericDAO< | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Pasemos ahora a explicar cada uno de los métodos de '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | <note important> | ||
+ | Los métodos que tiene el interfaz '' | ||
+ | * Separando el método '' | ||
+ | * Haciendo que el método '' | ||
+ | * Etc. | ||
+ | |||
+ | Un '' | ||
+ | </ | ||
+ | |||
+ | <note important> | ||
+ | En los interfaces '' | ||
+ | |||
+ | Por ejemplo en '' | ||
+ | |||
+ | Tambien en '' | ||
+ | </ | ||
+ | ===== La implementación ===== | ||
+ | Como ya hemos comentado la ventaja de usar el patrón [[patrones: | ||
+ | |||
+ | Para reutilizar el código se ha creado la clase '' | ||
+ | |||
+ | Veamos un diagrama UML con las relaciones: | ||
+ | |||
+ | <uml> | ||
+ | class GenericDAOImplHibernate | ||
+ | class ProfesorDAOImplHibernate | ||
+ | class UsuarioDAOImplHibernate | ||
+ | |||
+ | GenericDAOImplHibernate <|-- ProfesorDAOImplHibernate | ||
+ | GenericDAOImplHibernate <|-- UsuarioDAOImplHibernate | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | Ahora tenemos las 2 clases '' | ||
+ | |||
+ | En el siguiente diagrama UML puede verse los interfaces que implementa cada clase. | ||
+ | |||
+ | <uml> | ||
+ | |||
+ | class GenericDAO << | ||
+ | |||
+ | class ProfesorDAO << | ||
+ | class UsuarioDAO << | ||
+ | |||
+ | class GenericDAOImplHibernate | ||
+ | class ProfesorDAOImplHibernate | ||
+ | class UsuarioDAOImplHibernate | ||
+ | |||
+ | GenericDAO <.. GenericDAOImplHibernate | ||
+ | ProfesorDAO <.. ProfesorDAOImplHibernate | ||
+ | UsuarioDAO | ||
+ | </ | ||
+ | |||
+ | El código Java correspondiente a las 3 clases es el siguiente: | ||
+ | <code java 1 | GenericDAOImplHibernate.java> | ||
+ | public class GenericDAOImplHibernate< | ||
+ | |||
+ | |||
+ | SessionFactory sessionFactory; | ||
+ | |||
+ | private final static Logger LOGGER = Logger.getLogger(GenericDAOImplHibernate.class.getName()); | ||
+ | |||
+ | public GenericDAOImplHibernate() { | ||
+ | sessionFactory=HibernateUtil.getSessionFactory(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | @Override | ||
+ | public T create() throws BussinessException { | ||
+ | try { | ||
+ | return getEntityClass().newInstance(); | ||
+ | } catch (InstantiationException | IllegalAccessException ex) { | ||
+ | throw new RuntimeException(ex); | ||
+ | } catch (RuntimeException ex) { | ||
+ | throw ex; | ||
+ | } catch (Exception ex) { | ||
+ | throw new RuntimeException(ex); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void saveOrUpdate(T entity) throws BussinessException { | ||
+ | Session session = sessionFactory.getCurrentSession(); | ||
+ | try { | ||
+ | session.beginTransaction(); | ||
+ | session.saveOrUpdate(entity); | ||
+ | session.getTransaction().commit(); | ||
+ | } catch (javax.validation.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (org.hibernate.exception.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (RuntimeException ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw ex; | ||
+ | } catch (Exception ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new RuntimeException(ex); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public T get(ID id) throws BussinessException { | ||
+ | Session session = sessionFactory.getCurrentSession(); | ||
+ | try { | ||
+ | session.beginTransaction(); | ||
+ | T entity = (T) session.get(getEntityClass(), | ||
+ | session.getTransaction().commit(); | ||
+ | |||
+ | return entity; | ||
+ | } catch (javax.validation.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (org.hibernate.exception.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (RuntimeException ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw ex; | ||
+ | } catch (Exception ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new RuntimeException(ex); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void delete(ID id) throws BussinessException { | ||
+ | Session session = sessionFactory.getCurrentSession(); | ||
+ | try { | ||
+ | session.beginTransaction(); | ||
+ | T entity = (T) session.get(getEntityClass(), | ||
+ | if (entity == null) { | ||
+ | throw new BussinessException(new BussinessMessage(null, | ||
+ | } | ||
+ | session.delete(entity); | ||
+ | session.getTransaction().commit(); | ||
+ | } catch (javax.validation.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (org.hibernate.exception.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (BussinessException ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw ex; | ||
+ | } catch (RuntimeException ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw ex; | ||
+ | } catch (Exception ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new RuntimeException(ex); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public List< | ||
+ | Session session = sessionFactory.getCurrentSession(); | ||
+ | try { | ||
+ | |||
+ | Query query = session.createQuery(" | ||
+ | List< | ||
+ | |||
+ | return entities; | ||
+ | } catch (javax.validation.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (org.hibernate.exception.ConstraintViolationException cve) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new BussinessException(cve); | ||
+ | } catch (RuntimeException ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw ex; | ||
+ | } catch (Exception ex) { | ||
+ | try { | ||
+ | if (session.getTransaction().isActive()) { | ||
+ | session.getTransaction().rollback(); | ||
+ | } | ||
+ | } catch (Exception exc) { | ||
+ | LOGGER.log(Level.WARNING," | ||
+ | } | ||
+ | throw new RuntimeException(ex); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | private Class< | ||
+ | return (Class< | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java 1 | ProfesorDAOImplHibernate.java> | ||
+ | public class ProfesorDAOImplHibernate extends GenericDAOImplHibernate< | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java 1 | UsuarioDAOImplHibernate .java> | ||
+ | public class UsuarioDAOImplHibernate extends GenericDAOImplHibernate< | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | El código de '' | ||
+ | |||
+ | Destacar la línea 9 de '' | ||
+ | |||
+ | También destacar la simplicidad de las implementaciones para los interfaces '' | ||
+ | |||
+ | <note important> | ||
+ | La clase '' | ||
+ | </ | ||
+ | |||
+ | Ahora en un único diagrama UML se ven todas las relaciones entre los interfaces y las clases. | ||
+ | |||
+ | <uml> | ||
+ | note "Clase Generica con Tipos T e ID" as N1 | ||
+ | class GenericDAO << | ||
+ | GenericDAO : T create() | ||
+ | GenericDAO : void saveOrUpdate(T entity) | ||
+ | GenericDAO : T get(ID id) | ||
+ | GenericDAO : void delete(ID id) | ||
+ | GenericDAO : List< | ||
+ | |||
+ | N1 .. GenericDAO | ||
+ | |||
+ | class ProfesorDAO << | ||
+ | class UsuarioDAO << | ||
+ | |||
+ | GenericDAO <|.. ProfesorDAO | ||
+ | GenericDAO <|.. UsuarioDAO | ||
+ | |||
+ | class GenericDAOImplHibernate | ||
+ | class ProfesorDAOImplHibernate | ||
+ | class UsuarioDAOImplHibernate | ||
+ | |||
+ | GenericDAOImplHibernate <|-- ProfesorDAOImplHibernate | ||
+ | GenericDAOImplHibernate <|-- UsuarioDAOImplHibernate | ||
+ | |||
+ | GenericDAO <.. GenericDAOImplHibernate | ||
+ | ProfesorDAO <.. ProfesorDAOImplHibernate | ||
+ | UsuarioDAO | ||
+ | </ | ||
+ | |||
+ | Este diagrama UML contiene todos los intefaces y clases que se necesitan para implementar el patrón [[patrones: | ||
+ | ===== Creando un nuevo objeto DAO ===== | ||
+ | Para finalizar explicar los pasos necesarios para crear un objeto DAO de una nueva entidad. Para ello, lo haremos con el ejemplo de la entidad '' | ||
+ | |||
+ | * Crear un nuevo interfaz llamado '' | ||
+ | <code java > | ||
+ | public interface MunicipioDAO extends GenericDAO< | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | * Crear una nueva implementación llamada '' | ||
+ | <code java> | ||
+ | public class MunicipioDAOImplHibernate extends GenericDAOImplHibernate< | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Como vemos es sencillísimo crear un nuevo objeto DAO para una nueva entidad y sin nada de código repetido. | ||
+ | |||
+ | ===== Creando objetos DAO ===== | ||
+ | Ya sabemos cómo programar nuestros objetos DAO, pero ahora hay que añadirle el problema de crearlos desde nuestra aplicación. Aparentemente es tan sencillo como el siguiente código: | ||
+ | <code java> | ||
+ | UsuarioDAO usuarioDAO = new UsuarioDAOImplHibernate(); | ||
+ | ProfesorDAO profesorDAO = new ProfesorDAOImplHibernate(); | ||
+ | </ | ||
+ | |||
+ | Con esas dos simples líneas hemos creado 2 objetos DAO para las entidades Profesor y Usuario. Estas líneas se repetirán a lo largo del código cada vez que quedamos acceder a las entidades Profesor y Usuario. | ||
+ | |||
+ | ¿Cuál es el problema? | ||
+ | |||
+ | Que si queremos cambiar la implementación de '' | ||
+ | <code java> | ||
+ | UsuarioDAO usuarioDAO = new UsuarioDAOImplJDBC(); | ||
+ | ProfesorDAO profesorDAO = new ProfesorDAOImplJDBC(); | ||
+ | </ | ||
+ | Podríamos pensar que hacer un simple // | ||
+ | |||
+ | Hay varias soluciones a ésto pero hablaremos de la solución elegida en el siguiente tema sobre Spring. |