En esta entrada veremos cómo implementar el acceso a base de datos. Para ello, utilizaremos los repositorios de datos que Spring nos ofrece, y que nos harán la vida mucho más fácil. Concretamente, utilizaremos el repositorio de datos denominado CrudRepository, que como su propio nombre indica, nos posibilitará la realización de operaciones CRUD contra nuestra base de datos. Existe otro tipo de repositorio más completo que veremos en siguientes entradas.



Para utilizar este tipo de repositorio de Spring Framework, simplemente tendremos que crear una interfaz que extienda de CrudRepository, tal y como hemos hecho al crear la interfaz de acceso a datos LibroJpaRepository. Debemos especificar también, la clase que representa la entidad que va a ser gestionada por el repositorio, en este caso Libro, y el tipo de dato utilizado para representar la clave primaria en dicha entidad, en este caso un Integer (línea 6). Y nada más!


Las operaciones básicas de tipo CRUD las proporciona el propio repositorio sin necesidad de programar absolutamente nada más. Los métodos que proporciona el repositorio son los siguientes.
  • save(Libro libro): guarda o actualiza un libro y devuelve la entidad con el identificador asignado.
  • findOne(Integer id): devuelve un libro determinado.
  • findAll(): devuelve un Iterable<Libro> con todos los libros de base de datos.
  • count(): devuelve un dato de tipo Long con el número de libros.
  • delete(Integer id): borra un libro determinado.
  • exists(Integer id): retorna un boolean que informa de la existencia de un determinado libro.
Cada método se engloba en una transacción de forma automática, por lo que tampoco tendremos que gestionar las transacciones en este caso. Menos es más!

En la siguiente entrada hablaremos de las clases que van a consumir este repositorio de datos. Por una parte el controlador, que será el encargado de atender las peticiones HTTP y servir los datos, y por otra parte la clase que hará las veces de fachada (patrón facade), encapsulando la lógica de negocio necesaria para atender las peticiones que llegan al controlador y realizar las consultas a base de datos pertinentes por mediación del repositorio de datos.
Pulsa aquí para acceder al código de esta entrada en mi repositorio Github
Es el turno de ver cómo podemos anotar nuestras entidades para que Hibernate pueda gestionarlas de forma adecuada con el fin de realizar los mapeos correspondientes con la base de datos.



En este caso, anotaremos la clase Libro, que se encuentra en el paquete spring.rest.jpa.i.bean. Recordemos que este paquete es el que se ha indicado en la configuración del entityManagerFactory del fichero applicationContext.xml, para que Spring pueda encontrar anotaciones como las siguientes.
  • @Entity (línea 10): indica que es una entidad que tendrá representación en base de datos.
  • @Table (línea 11): se utiliza para especificar la tabla a la que representa la clase, mediante la propiedad name. Esta anotación no es necesaria si la tabla tiene el mismo nombre que la clase.
  • @Id (línea 14): necesaria para identificar la propiedad de la clase que representa a la clave primaria de la tabla en base de datos.
  • @GeneratedValue (línea 15): se utiliza para especificar la estrategia de generación de la clave primaria. En este caso, se utiliza IDENTITY, que es la que hemos utilizado para configurar la estrategia de generación de claves primarias en la tabla libros. Mediante esta estrategia, HSQL genera un identificador de forma automática cada vez que se inserta un nuevo libro. Existen otras estrategias de generación de claves primarias (más info.). 
  • @Column (líneas 18 y 22): esta anotación se utiliza para mapear las propiedades de la clase con las columnas en base de datos. Si la propiedad tiene un nombre diferente al de la columna, se usa la propiedad name para indicar el nombre, tal y como hemos hecho en la línea 22.


Pulsa aquí para acceder al código de esta entrada en mi repositorio Github
Seguimos con esta segunda entrada dedicada a la implementación de una API RESTful con Spring Framework. En esta ocasión, veremos los detalles de configuración.



A continuación, detallaremos los siguientes ficheros de configuración para finalizar con unas breves conclusiones:

applicationContext.xml

El fichero applicationContext.xml corresponde al contexto raíz de nuestro servicio. Es aquí donde se declaran las clases o beans de nivel general para que Spring pueda gestionarlos. Los beans configurados son los siguientes.
  • dataSource (línea 20): indica la fuente de datos, en este caso una base de datos embebida de tipo HSQL. 
  • jpaVendorAdapter (línea 25): necesario para indicar a Spring, que será Hibernate el framework que utilizaremos como proveedor JPA.
  • entityManagerFactory (línea 30): será el objeto que Spring utilizará para interactuar con la base de datos. Hay dos propiedades fundamentales.
    • packagesToScan: indica el paquete donde se encuentran los beans que representan las entidades de nuestro servicio, en este caso, libros. Como veremos más adelante, estas entidades estarán anotadas para que Hibernate pueda relacionarlas con su correspondiente representación en base de datos.
    • jpaProperties: aquí se especifican las propiedades de Hibernate. En esta ocasión, se ha especificado el dialecto de base de datos a utilizar y el esquema por defecto, para que Hibernate cree las consultas SQL de forma adecuada.
  • transactionManager (línea 44): declaración del tipo de gestor transaccional, en este caso JPA.
  • databaseManager (línea 49): posibilita el uso de un gestor de base de datos HSQL. Este bean es opcional, pero el gestor permitirá modificar los datos fácilmente para la realización de pruebas.

dispatcher-servlet.xml

El fichero dispatcher-servlet.xml contiene la declaración de aquellos beans que están directamente relacionados con el servicio a implementar. A partir de esta configuración, Spring creará un Servlet que gestionará las peticiones que se realicen a la API, redireccionándolas a los controladores correspondientes. 

En lugar de declarar los beans en el fichero XML de forma explícita, se ha optado por una configuración mediante anotaciones en las propias clases Java. Para ello, se han declarado las etiquetas necesarias para que Spring pueda detectar en qué clases se encuentran estas anotaciones.
  • En la línea 18 se especifica el paquete raíz a partir del cual Spring buscará beans de nuestra lógica de negocio (servicios, componentes, etc.)
  • En la línea 21 se especifica el paquete donde están los repositorios JPA que se utilizarán para acceder a base de datos,
  • En la línea 24 se configuran las transacciones mediante anotaciones
  • En la línea 26 se especifica que los controladores que procesarán las peticiones estarán también anotados.
Existen dos contextos de aplicación: un contexto raíz (applicationContext) y otro hijo (dispatcher-servlet). Los beans definidos en el contexto hijo tienen acceso a los definidos en el padre, pero no al revés. Es por ello que en el dispatcher-servlet se encuentran los componentes específicos del servicio web (p.ej. controllers), y en el applicationContext se encuentran los componentes generales (p.ej. acceso a datos).

web.xml

En el fichero web.xml se declara el dispacher-servlet para su inicialización al desplegar el servicio web en el servidor, indicando el fichero en el que se encuentra su configuración (línea 12). En las líneas 20 y 23 se especifica un listener necesario para que Spring inicialice el contexto de aplicación y la ubicación del fichero con su configuración.

Conclusiones 

En la versión actual de Spring Framework, la posibilidad de anotar las propias clases Java simplifica mucho la configuración de nuestro servicio. En siguientes entradas, veremos cómo se deben realizar las anotaciones de las entidades, controladores, etc.
Pulsa aquí para acceder al código de esta entrada en mi repositorio Github
Estreno blog con una serie de entradas en las que veremos cómo implementar una API RESTful sobre plataforma Java utilizando diversos módulos del siempre maravilloso Spring. Concretamente, utilizaremos el módulo principal Spring Framework y el módulo Spring Data. De este último, usaremos las funcionalidades para acceso a datos mediante JPA (Java Persistence API), utilizando Hibernate como proveedor JPA.

Para ponernos en situación, vamos a suponer que queremos implementar una API que nos permita gestionar todos los libros que tenemos en nuestra biblioteca personal. En esta primera entrada veremos cómo definir algunos servicios básicos de tipo CRUD (Create Read Update Delete) para una gestión inicial de los libros.

Las herramientas necesarias para seguir esta serie de entradas son las siguientes:
Concretamente, en esta entrada trataremos los siguientes puntos de cara a la implementación del servicio, que iremos completando en siguientes entradas.

Definición de los servicios

Empezaremos definiendo los servicios REST para una gestión básica de los libros. Para ello, contaremos con los siguientes servicios:
  • GET /libros: obtener una lista de todos los libros de la biblioteca.
  • GET /libros/1: obtener un libro concreto por su identificador.
  • POST /libros: crear un nuevo libro.
  • PUT /libros/1: actualizar un libro concreto por su identificador.
  • DELETE /libros/1: borrar un libro concreto por su identificador.
Es recomendable que los nombres (nunca verbos) que utilicemos para identificar los servicios estén en su forma plural en base al recurso gestionado, tal y como hemos especificado con nuestros libros. Existen multitud de buenas prácticas para la implementación de servicios REST. En este y este enlace podréis encontrar multitud de buenos consejos.

Definición de la base de datos

A continuación, definiremos la base de datos para almacenar los libros. Inicialmente, contaremos con un identificador, el nombre y el año de publicación de cada libro. El siguiente esquema, corresponde a la creación de la tabla para almacenar las propiedades mencionadas de cada libro. Este esquema se basa en la sintaxis de la base de datos HSQLDB, la cual usaremos en su modo embebido para este ejemplo.

En la línea 2 podemos observar la creación de la clave primaria mediante la instrucción IDENTITY, la cual creará una clave auto-incremental en base de datos de forma automática.
Además, hemos creado un script para insertar nuestros primeros libros de forma automática cuando el servicio se despliegue.


Estructura del proyecto

El proyecto está soportado por Maven. En el enlace que se encuentra al final del post encontrarás el acceso a mi repositorio Github para que puedas descargar el código del proyecto y empieces a trastear con él. La estructura del proyecto es la que se muestra a continuación.


En esta estructura, podemos encontrar diferentes paquetes con clases Java.
  • bean: paquete donde se encuentran las entidades Java que representan los recursos, en este caso libros.
  • controller: aquí se encuentran los controladores que se encargarán de procesar las peticiones que lleguen para gestionar los libros (GET, POST, PUT y DELETE)
  • facade: en este paquete se encuentran las clases donde se implementa la lógica de negocio, siguiendo el patrón facade
  • repository: aquí se encuentran las clases que implementarán el acceso a la base de datos.
Además, encontramos los esquemas de creación de la base de datos e inserción de datos en la carpeta db. También tenemos los ficheros de configuración de Spring (applicationContext.xml y dispacherServlet.xml) en la carpeta del mismo nombre, así como el fichero de Maven pom.xml con las dependencias y plugins necesarios para el despliegue del servicio.

Despliegue del servicio 

El servicio implementado se despliega en un servidor Tomcat que ya se incluye embebido en el proyecto. Para ello, hay que ejecutar el comando Maven siguiente: clean tomcat7:run
Esto iniciará el servicio, creando de forma automática la base de datos e insertando los datos que se encuentran en el script db/insert.sql. Verás que también se abre una ventana con el manager de gestión de datos para la base de datos embebida HSQL. Desde aquí podremos consultar y realizar modificaciones de nuestros datos directamente.

Para interactuar con el servicio, podemos acceder a la URL http://localhost:8080/spring.rest.jpa.i/libros mediante el cliente Advanced Rest Client o mediante un navegador web. Esta petición nos devolverá un listado de libros en formato JSON.


Conclusiones

En siguientes entradas explicaré cómo hemos implementado las diferentes clases (beans, controllers, etc.) y la configuración de Spring, además de completar esta API con nuevos servicios, más entidades, nuevas relaciones entre entidades, etc. También, veremos otros temas relacionados con el diseño de la API, como el versionado, la seguridad, cacheo, serialización avanzada, etc. De esta forma iremos tratando diferentes configuraciones y funcionalidades que nos ofrece Spring Data JPA para hacernos la vida más fácil y placentera.

Pulsa aquí para acceder al código de esta entrada en mi repositorio Github