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:
- 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
- Crearemos los beans, uno por cada entidad de la BD, tal y como en la entrada anterior.
- 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.
- 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.
- 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:
- Crearemos una interface del objeto de negocio que debe interactuar con el DAO.
- Implementaremos esta interface.
- 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.