​
Mostrando entradas con la etiqueta DAO. Mostrar todas las entradas
Mostrando entradas con la etiqueta DAO. Mostrar todas las entradas

martes, 30 de abril de 2013

Introducción a Spring JDBC como solución a los problemas de uso e JDBC en proyectos productivos. (II)

En la primera parte de esta entrada vimos la teoría y diseño detrás del framework Spring JDBC. En esta entrada estaremos viendo cómo funciona en la práctica.

Estaremos usando la misma BD de la entrada "Uso de JDBC. Sus limitaciones."

Como IDE usaré el STS o SpringTollSuite

 

Fig.1. Imagen inicial de SpringIDE.

Lo que haremos será lo siguiente:

  1. Crearemos  un proyecto JAVA y le agregaremos las dependencias de Spring, esto lo pueden ver como se hace en esta entrada: http://www.giantflyingsaucer.com/blog/?p=1524  
  2. Crearemos los beans, uno por cada entidad de la BD, tal y como en la entrada anterior.
  3. Diseñaremos las interfaces DAO y realizaremos su implementación tal y como se expresa en la figura 1 de la entrada I. Es importante destacar que los métodos de la clase interface serán todas las operaciones que se quieran realizar sobre los DAO.
  4. En las implementaciones de las interfaces DAO estaremos usando la plantilla JdbcTemplate y veremos como esta se crea inyectándole la fuente de datos. Algo propio de Spring.
  5. Por ultimo veremos el fichero de configuración con una configuración mínima para la fuente de datos y la carga de los beans.

Empecemos.

La estructura del proyecto la pueden ver en esta imagen:


 Fig.2. Estructura del proyecto creado.

Como pueden ver creo una estructura de paquetes donde tengo los DAO que son los beans para cada entidad de la BD.

Tengo un paquete para las interfaces donde se declaran los métodos que representan las acciones sobre las tablas de la BD.

Tengo otro paquete para las implementaciones de estas interfaces y es en estas implementaciones donde usaremos la plantilla con el código nuevo a explicar, porque todo lo demás es lo mismo de siempre.

Finalmente tengo un paquete para las pruebas, como aún no hemos escrito nada sobre pruebas con JUnit pues las pruebas son muy burdas pero cumplen su objetivo.

Si se fijan también verán un fichero spring-config.xml que es donde almacenamos las configuraciones y pueden ver también algunas de las librerías que se necesitan para poder ejecutar el proyecto y que listamos a continuación. Esto cuando introduzcamos Maven pues no se gestionará automáticamente. De momento este es el listado:

commons-dbcp-1.2.2.jar

commons-logging-1.1.1.jar

commons-pool-1.5.6.jar

org.springframework.aop-3.1.0.RELEASE.jar

org.springframework.asm-3.1.0.RELEASE.jar

org.springframework.aspects-3.1.0.RELEASE.jar

org.springframework.beans-3.1.0.RELEASE.jar

org.springframework.context.support-3.1.0.RELEASE.jar

org.springframework.context-3.1.0.RELEASE.jar

org.springframework.core-3.1.0.RELEASE.jar

org.springframework.expression-3.1.0.RELEASE.jar

org.springframework.instrument.tomcat-3.1.0.RELEASE.jar

org.springframework.instrument-3.1.0.RELEASE.jar

org.springframework.jdbc-3.1.0.RELEASE.jar

org.springframework.jms-3.1.0.RELEASE.jar

org.springframework.orm-3.1.0.RELEASE.jar

org.springframework.oxm-3.1.0.RELEASE.jar

org.springframework.test-3.1.0.RELEASE.jar

org.springframework.transaction-3.1.0.RELEASE.jar

org.springframework.web.portlet-3.1.0.RELEASE.jar

org.springframework.web.servlet-3.1.0.RELEASE.jar

org.springframework.web.struts-3.1.0.RELEASE.jar

org.springframework.web-3.1.0.RELEASE.jar

postgresql-9.1-901.jdbc4.jar

Si se fijan  he puesto todas las librerías que vienen con la distribución de spring, aunque no las usemos todas pero en aras de ahorrar tiempo, también agregué la del driver de postgresql y algunas commons para manejar las conexiones.

Bien una vez creado el proyecto siguiendo el enlace que les compartí y añadidas estas clases a la carpeta lib, que tienen que crear, y puestas en el classpath les muestro la estructura de una clase que mapea a una entidad de la BD.



Fig.3. Clase que representa al bean para la entidad  capítulo.

Como pueden ver es muy básica, ya la habíamos visto en otra entrada, así que no comentaremos nada de aquí.

La declaración de su interface le sigue:

 

Fig.4. Interface para el DAO.

También muy básica, solo pondremos 2  métodos. Uno para listar todos los capítulos y otro para añadir un capitulo.

Su implementación es la que nos interesa, veamos cómo se hace.

 

Fig.5. Implementación del DAO que incluye el uso de la plantilla de spring para JDBC.

Como pueden ver comenzamos anotando, de momento no se preocupen por entender esto ya en otra entrada lo explicaré con detalle, la clase CapituloDAO con @Repository y diciendo que implementa la interface ICapitulo.

Luego declaramos las consultas en variables y una última variable de tipo la plantilla que usaremos.

Implementamos un método que recibe un Datasource y con este objeto crea una plantilla y se la asigna a la variable antes creada. Este método también está anotado con @Autowired.

Luego vienen los métodos para listar los capítulos, vean que poco de código hay que escribir. Es solo decirle al template que nos ejecute la consulta que tenemos en CAPITULO_SELECT y pasarle un objeto de tipo RowMapper y es aquí donde pasa la magia porque por cada tupla de la BD que represente un capitulo se llamará al método mapRow que se encarga de crear un objeto de tipo Capitulo y asignarle los valores que vienen en la tupla y devolver el objeto de tipo Capitulo ya creado. Luego de procesadas todas las tuplas pues se devuelve el listado de los capítulos.

En el caso de añadir un libro pues es más fácil aun.  Se llama al método update de la plantilla, se le pasa la consulta que se definió en CAPITULO_INSERT y se le pasa un arreglo de objetos que se corresponden con los valores de los atributos de la clase pasada al método y que se desea insertar en la BD.

Aquellos que quieran mejorar este paso de los parámetros a la consulta pueden usar la plantilla NamedParameterJdbcTemplate. Con esta plantilla le ponemos nombre a los parámetros y así no importa el orden en que los pasemos, algo muy importante por si se hacen cambios en la estructura de la BD y se altera el orden de los campos en la BD o en la consulta.

Ahora veremos cómo es que se especifica el fichero de configuración para spring, porque si recuerdan el código de la entrada de JDBC aún no he puedo cómo crear la conexión a la BD. Ahora lo veremos.


Fig.6. Contenido del fichero de configuración de Spring.

Como pueden ver solo creamos un bean con id=dataSource que es el que le inyectamos al método que se encarga de  crear el template, de esto se encarga Spring JDBC y creamos otro bean para el manejo de las transacciones para el método de insertar. No hay que crear más beans aquí porque estos son creados al vuelo por spring gracias a las anotaciones que les comentaba anteriormente y que les explicaré cómo funcionan en otra entrada.

Para comprobar que esto de verdad funciona pues haremos lo siguiente:

  1. Crearemos  una interface del objeto de negocio que debe interactuar con el DAO.
  2. Implementaremos esta interface.
  3. Usaremos una clase para cargar la configuración de spring y crear un objeto de negocio para acceder a la capa de persistencia.

Esta es la interface:


Fig.7. Interface de la clase del negocio que usará la capa de persistencia definida.

Y esta es su implementación:

 

Fig.8. Implementación de la clase de negocio.

Vean que sencillo es el código para interactuar con la BD. De ahí no sabemos cuál es el motor de persistencia que se está usando ni las complejidades del mismo.

Noten las anotaciones @Service, @Autowired y @Transactional.

La clase que consumirá esta implementación es la siguiente:

 

Fig.9. Clase de prueba para comprobar el funcionamiento de la capa de persistencia.

Y cuando la ejecutamos vemos lo siguiente:


Fig.10. Resultado en la consola.

Como pueden ver si listan todos los títulos existentes en la BD como pueden ver aquí:

 

Fig.11. datos en la BD antes de ejecutar las consultas a la BD.

Y se inserta un nuevo libro en la BD que podemos verlo a continuación:

 

Fig.12. Imagen que muestra el libro insertado luego de ejecutar el código de prueba.

Y bueno eso es todo. Quedan algunas cosas pendientes como:

  • Depurar un poco la implementación para mejorar el código. Es de ejemplo pero  siempre se puede mejorar.
  • Capturar información para hacer logging.
  • Revisar el trabajo con spring y con las anotaciones.
  • Ver el uso de otras plantillas para JDBC.
  • Ver como probar con JUnit.
  • Ver cómo se pueden gestionar las dependencias para no tener que agregarlas manualmente.

Son cosas que poco a poco iremos tocando en el blog porque son básicas para cualquier desarrollo serio.

Espero les haya resultado de utilidad y esperamos sus comentarios.

{ Leer Más }


lunes, 29 de abril de 2013

Introducción a Spring JDBC como solución a los problemas de uso e JDBC en proyectos productivos. (I)

En una entrada anterior les había comentado sobre JDBC y sus limitaciones que más que limitaciones eran problemas. Estos problemas se resumían en:

  • Se debe escribir demasiado código para cosas simples como operaciones CRUD.
  • Mucho del código a escribir es repetitivo lo que puede llevar a errores o inconsistencias.
  • Se debe manejar la creación de las conexiones, la preparación de las consultas su ejecución y el cierre de las conexiones.
  • Se debe manejar las excepciones, lo cual no vimos en la entrada, pero siempre es algo que hay que hacer con JDBC.

Pues bueno en esta entrada les traigo una solución para aquellos que quieren seguir usando JDBC, bien porque les gusta y no quieren aprender un nuevo framework o bien porque su proyecto es pequeño o mediano y no ven la necesidad de usar un cañón para matar un mosquito la solución es usar el framework "Spring JDBC".

Para comenzar en este framework quisiera comentarles primero sobre los DAO. Este es un acrónimo de  "Data Access Object" un patrón de diseño muy común que se usa para diseñar como los objetos de negocio de una aplicación deben usar los objetos encargados del acceso a los datos.

Lo pueden ver en esta imagen:


Fig.1. Esquema que ilustra el patrón DAO.

Como pueden ver los objetos del negocio acceden a los DAO a través de sus interfaces, de esta manera no dependen de una implementación en específico lo que hace que esta implementación se pueda cambiar fácilmente. También facilita las pruebas que se pueden realizar sobre esta implementación, ya que se pueden crear implementaciones falsas menos complejas que las implementaciones reales con fines de prueba.

Esta manera de separar la capa de acceso a datos y su implementación del resto del código de la aplicación es usada por Spring para entre otras muchas cosas manejar las excepciones. El argumento se basa en que casi todas las excepciones generadas por JDBC no se pueden recuperar por lo que Spring ha definido sus propias excepciones que se mapean de la siguiente manera:


Fig.2. Excepciones de JDBC y de Spring JDBC.

Lo importante de este mapeo es que no es específico para JDBC, si no para cualquier framework de persistencia como puede ser hibernate, lo que contribuye al uso del patrón DAO.

Hay que tener en cuenta que estas excepciones no necesitan de los bloques catch tan comunes ya que las excepciones no son chequeables. No necesitan serlo ya que no se puede hacer prácticamente nada con ellas.

Lo otro que hace Spring JDBC es crear una especie de plantillas para agrupar todas aquellas cosas que son repetitivas dentro del código para acceder a los datos. Recuerdan los problemas listados al inicio, pues estas plantillas resuelven si no todos la mayoría. Vean cómo funcionan.


Fig.3. Esquema de funcionamiento de las plantillas en Spring para el acceso a los datos.

La plantilla creada agrupa todas aquellas acciones que son repetitivas y nos las oculta, y solo nos deja encargarnos de lo que de verdad es útil. Ejecutar las consultas y retornar la información generada por estas consultas.

Spring ha definido numerosas plantillas para diferentes frameworks de persistencia como pueden ver en esta imagen.


Fig.4. Listado de las clases  y plantillas que soporta Spring para el acceso a datos.

Llegado a este punto vemos que es necesario crear un mecanismo de callback para poder usar la plantilla. O sea que nuestros DAO deben de tener una propiedad de tipo la plantilla que usaremos y debe definir los métodos get/set para manejar esta propiedad. Aunque esto no es incómodo de hacer si se repite bastante cuando tenemos muchos DAO y para cada uno de ellos puede debemos de incorporar la misma plantilla.

Spring también nos libera de esto a través del uso de métodos dentro de las plantillas que nos ayudan a no tener que implementar estos callback. De esta manera Spring define clases de soporte de las cuales podemos extender con nuestras propias implementaciones. Vean su diseño:


Fig.5. Esquema de diseño de los DAO de soporte en Spring.

De esta manera podemos tener una clase DAO support de la cual extendemos para crear nuestros DAO y de esta manera pues el manejo de la plantilla se hace de forma transparente para los desarrolladores.

Aquí les dejo el listado de DAO de soporte que da Spring y el acceso que proveen.


Fig.6. Listado de las clases de soporte DAO y el acceso que brindan.

Para terminar esta entrada solo comentarles que con el framework Spring JDBC y sus componentes que ya he identificado el código a escribir se reduce de forma significativa y lo podremos ver en la próxima entrada que será la parte práctica de esta introducción.

{ Leer Más }


IconIconIcon