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. | ||