lunes, 18 de mayo de 2015

JAVA implementación Patrón Generic Dao

Que tal, en esta oportunidad se desea realizar la implementación del patrón GENERIC DAO y GENERIC SERVICE en una arquitectura empresarial JAVA con las tecnologías de SPRING para la capa de servicio e HIBERNATE para persistencia, pero antes vamos a comprender que significa este patrón de diseño.

GENERIC DAO: Como su nombre lo indica es es un patrón de diseño o llámese también practica de programación que busca reutilizar código mediante la implementación de operaciones básicas que se desea implementar en variedad de clases, un ejemplo de ello son las operaciones de crear, consultar, listar, eliminar, y modificar (CRUD) que generalmente tienen las clases dao,
Su técnica de implementación consiste en definir una clase que implementa una interfaz genérica que tendrá definidas estas operaciones y así mismo su implementación, a partir de esto las demás clases heredaran sus metodos mediante el atributo extends, como resultado podremos realizar todas estas operaciones solo con la creación e instanciamiento de la clase Dao sin necesidad de volver a declarar dichos métodos, a largo plazo esto representa una gran reutilización de código que permitirá realizar el mantenimiento de nuestra aplicación de forma mas sencilla.

Creación de interfaz GenericDao:

_________________________________________________________________________________


public interface GenericDao<T> {     T insertar(T t);
    void eliminar(T t);
    T encontrarPorId(Long id);
    T actualizar(T t);  
    List<T> listar();  
}
_________________________________________________________________________________


Creación de la clase GenericDaoImpl:

public abstract class GenericDaoImpl<T> implements Serializable, GenericDao<T> {

private static final long serialVersionUID = 1020243919685111719L;

protected SessionFactory sessionFactory;

private Class<T> entityClass;

@SuppressWarnings({ "unchecked", "rawtypes" })
@Autowired
public GenericDaoImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
Type t = getClass().getGenericSuperclass();
         ParameterizedType pt = (ParameterizedType) t;
         this.entityClass = (Class) pt.getActualTypeArguments()[0];
}

protected Session currentSession() {
return sessionFactory.getCurrentSession();
}

@SuppressWarnings("unchecked")
public List<T> listar() {
return currentSession().createQuery("SELECT e FROM "+this.entityClass.getSimpleName()+" e").list();
}

@SuppressWarnings("unchecked")
public T encontrarPorId(Long t) {
return (T) currentSession().get(this.entityClass, t);
}

public T insertar(T t) {
currentSession().saveOrUpdate(t);
return t;
}

public T actualizar(T t) {
currentSession().merge(t);
return t;
}

public void eliminar(T t) {
currentSession().delete(t);
}

}
_________________________________________________________________________________


Interface para el acceso a datos de personas PersonaDao:
_________________________________________________________________________________

public interface PersonaDao extends GenericDao<Persona> {

}
_________________________________________________________________________________


Clase implementación para el acceso a datos de personas PersonaDaoImpl: Heredara los atributos e implementación de metodos de GenericDaoImpl, ademas implementa la interfas PersonaDao que a su vez hereda la declaración de los metodos de insertar, actualizar, eliminar permitiendo que estos esten disponibles al llamar esta clase desde un servicio,
_________________________________________________________________________________

@Repository
public class PersonaDaoImpl extends GenericDaoImpl<Persona> implements PersonaDao {

private static final long serialVersionUID = -1745907453415561590L;

@Autowired
public PersonaDaoImpl(SessionFactory sessionFactory) {
super(sessionFactory);
}

}
_________________________________________________________________________________

La anterior implementación permitira que todas nuestra clases Daos que extiendan del Generic tenga los metodos del CRUD basico por defecto sin necesidad de su declaración o implementación, a continuación este será el resultado desde el llamado de un servicio.




Implementación de GenerciService: GenericServices nos permitirá disponer de las operaciones CRUD para cualquier de nuestros servicios que extiendan de la clase GenericService, a continuación se presenta la implementación de GenericService.

Codigo de interfas PersonaService.
_________________________________________________________________________________

public interface PersonaService extends GenericService<Persona> {
}

_________________________________________________________________________________

Codigo de clase PersonaServiceImpl.
_________________________________________________________________________________

@Service("personaService")
@Transactional
public class PersonaServiceImpl extends GenericServiceImpl<Persona>  implements PersonaService {

private static final long serialVersionUID = 6641349706597372948L;


@Autowired
public PersonaServiceImpl(PersonaDao personaDao) {
this.setGenericDao(personaDao);
}

}

_________________________________________________________________________________


Archivos de configuración de Spring.

Archivo application-context.xml: Encargado de realizar la detección automática de servicios y repositorios bajo el uso de anotaciones @service, @autowired de spring.
_________________________________________________________________________________

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="co.com.sp.capapersistencia" />
<context:component-scan base-package="co.com.sp.capaservicio" />

</beans>
____________________________________________________________________


Archivo datasource.xml: Encargado de definir la conexión con base de datos, el driver utilizado y el bean para manejo de transacciones.
_________________________________________________________________________________

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/my_bd_nombre" />
<property name="username" value="usuario" />
<property name="password" value="contraseña" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" p:dataSource-ref="dataSource">
<property name="packagesToScan">
<list>
<value>co.com.sp.capadominio</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.format_sql=true hibernate.show_sql=true
hibernate.dialect=org.hibernate.dialect.H2Dialect</value>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory" />

</beans>
_________________________________________________________________________________



2 comentarios:

  1. Parece interesante tu aporte pero si hicieras algo para dar formato al código fuente me animaría a leerlo completo.

    ResponderEliminar