Spring boot se ha convertido en uno de los frameworks más fáciles de utilizar en Java para distintos tipos de aplicaciones, en este post explicaremos la integración de Spring boot con la base de datos H2 para el desarrollo y pruebas de nuestras aplicaciones.
¿Qué es H2?
H2 es una base de datos relacional llamada In memory database (Base de datos en memoria), esto significa que los datos solo vivirán durante la ejecución de nuestra aplicación y cuando esta termine se perderán. El uso de este tipo de bases de datos es muy común para desarrollar pruebas de concepto y realizar pruebas unitarias.
Las bases de datos en memoria son diferentes a las bases de datos normales por lo siguiente, al usar una base de datos común hacemos lo siguiente:
Como podemos ver la aplicación y la base de datos son independientes, esto significa que se debe crear la base de datos y mantenerla para poder tener acceso a ella. A diferencia de esto, una base de datos en memoria funcionará del siguiente modo:
Como vemos una vez que iniciemos nuestra aplicación se iniciará nuestra base de datos y esta vivirá durante el tiempo que nuestra aplicación funcione, una vez que la aplicación se detiene los datos se pierden, es por esto que el uso de este tipo de bases de datos es ideal para el desarrollo de pruebas de concepto y tests unitarios dentro de nuestras aplicaciones.
Ventajas
El uso de H2 proporciona las siguientes ventajas:
- No es necesario invertir en infraestructura
- No es necesario invertir en configuración
- No es necesario dar mantenimiento
- La configuración con Spring boot es super simple
Funcionamiento con Spring boot
Una vez que entendemos el propósito de H2 veamos como funciona con Spring boot.
Paso 1: Configuración
El primer paso será configurar nuestra aplicación Spring boot, veamos las entradas en nuestro archivo pom.xml:
org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE
Define el proyecto padre de nuestra aplicación (Configuración común de spring boot).
org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-web com.h2database h2 runtime
Las anteriores son las dependencias necesarias de nuestro proyecto, en este caso solo explicaremos como trabajar con h2 utilizando el api de spring-data.
maven-compiler-plugin 1.8 1.8 org.springframework.boot spring-boot-maven-plugin
Por último vemos la definición de plugins los cuál nos permitirán ejecutar nuestra aplicación y definir la versión de java a utilizar.
Paso 2 : Definir nuestra clase aplicación
Una vez que definimos nuestras dependencias el siguiente paso será crear nuestra clase Application.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author raidentrance * */ @SpringBootApplication @EnableTransactionManagement @EnableJpaRepositories("com.devs4j.app.repositories")<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span> public class H2SampleApplication { public static void main(String[] args) { SpringApplication.run(H2SampleApplication.class, args); } }
Ejecutaremos esta clase para iniciar nuestra aplicación.
Paso 4: Crear una Entity
En este ejemplo utilizaremos Spring data para ver el funcionamiento de H2, para esto crearemos la siguiente Entity:
@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name", nullable = false) private String name; @Column(name = "nickname", nullable = true) private String nickName; @Column(name = "age", nullable = false) private Integer age; ....Getters and setters }
La clase anterior define una entidad persona con las siguientes características:
- Un Id de tipo entero autoincremental
- Un nombre de tipo String que debe ser not null
- Un nickName de tipo String que puede ser null
- Una edad de tipo Integer que debe ser not null
Paso 6 : Crear repository JPA
Como sabemos Spring Data nos permite simplificar el código de acceso a base de datos a través de Repositories, veamos el repositorio a crear:
import org.springframework.data.jpa.repository.JpaRepository; import com.devs4j.app.entities.Person; /** * @author raidentrance * */ public interface PersonRepository extends JpaRepository{ }
Como se puede ver PersonRepository nos permitirá manejar entidades de tipo Person, más adelante veremos como utilizaremos esta interfaz en nuestro código.
Paso 7 : Creando el servicio
El siguiente paso será crear un servicio de Spring, estos servicios son diseñados para escribir la lógica de negocio que necesitemos, en este caso no es tan necesario ya que solo ejecutará la llamada a un repository, pero en casos en los que hace llamadas a multiples repositorios y ejecuta alguna lógica sobre los datos, es muy útil.
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.devs4j.app.entities.Person; import com.devs4j.app.repositories.PersonRepository; /** * @author raidentrance * */ @Service public class PersonService { @Autowired private PersonRepository repository; public List getPeople() { return repository.findAll(); } }
Como se puede ver a través de la anotación @Autowired inyectamos el repository dentro de nuestro servicio, recordemos que no es necesario escribir la implementación del repository ya que Spring Data lo hace por nosotros, lo se es hermoso :).
Paso 8 : Creando el controller
El último paso para completar nuestra aplicación será crear un Controller para exponer la información, veamos el código a continuación:
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.devs4j.app.entities.Person; import com.devs4j.app.services.PersonService; /** * @author raidentrance * */ @RestController @RequestMapping("api") public class PersonController { @Autowired private PersonService personService; @RequestMapping("/people") @ResponseBody public ResponseEntity<List> getPeople() { return new ResponseEntity(personService.getPeople(), HttpStatus.OK); } }
Como vemos nuestro endpoint /api/people devolverá todos los registros que se encuentren en la tabla person.
Paso 9: Ejecutando nuestra aplicación
En este paso ejecutaremos la clase H2SampleApplication.java y llamaremos la url http://localhost:8080/api/people, al hacer esto obtendremos la siguiente salida:
[ ]
Triste ¿no lo creen? no vemos ningún registro porque nuestras tablas en memoria están vacías, veamos algunas formas de llenarlas.
Trabajando con H2
Como comentamos al principio del post, H2 es una base de datos en memoria, lo cual significa que mantendrá nuestros registros mientras nuestra aplicación esté en ejecución, lo primero que haremos será ver como acceder a la base de datos mientras la aplicación esta en ejecución.
Accediendo a la consola de H2
Lo primero que debemos aprender es a utilizar la consola de H2, para esto agregaremos la siguiente línea a nuestro archivo /src/main/resources/application.properties:
spring.h2.console.enabled=true
Esto nos permitirá habilitar la consola de administración de H2 mientras nuestra aplicación se ejecuta. Una vez hecho esto iniciaremos nuestra aplicación y accederemos a la URL http://localhost:8080/h2-console, esto nos mostrará la siguiente vista:
Es importante cambiar la JDBC URL a jdbc:h2:mem:testdb y oprimir el botón connect, una vez hecho esto veremos lo siguiente:
Como pueden ver hay una tabla llamada PERSON, nosotros no creamos esta tabla si no que fue creada de forma automática por H2 y spring boot, desde esta consola podremos ejecutar sentencias sql para agregar valores, modificarlos o realizar consultas durante la ejecución de nuestra aplicación.
Lo anterior nos da flexibilidad para realizar modificaciones en nuestros datos, pero si nuestra aplicación require que se carguen algunos scripts o que se inserten algunos valores de ejemplo tenemos otra forma de hacerlo, a través de los siguientes archivos:
- schema.sql : Permite ejecutar sentencias DDL antes de ejecutar la aplicación
- init.sql : Permite realizar sentencias DML una vez que nuestro archivo schema.sql se ejecutó de forma correcta.
Veamos un ejemplo, crearemos el archivo /src/main/resources/data.sql con las siguientes sentencias:
insert into person (id,name,nickname,age)values(1, 'alex','raidentrance',29); insert into person (id,name,nickname,age)values(2, 'juan','juanito dubalin',80); insert into person (id,name,nickname,age)values(3, 'pedro','mascara sagrada',29);
Como se puede ver solo son sentencias insert que generarán algunos valores de ejemplo en nuestra base de datos.
A continuación solo debemos detener nuestra aplicación y ejecutarla de nuevo, al hacerlo podremos ejecutar el endpoint http://localhost:8080/api/people y veremos la siguiente salida:
[ { "id": 1, "name": "alex", "nickName": "raidentrance", "age": 29 }, { "id": 2, "name": "juan", "nickName": "juanito dubalin", "age": 80 }, { "id": 3, "name": "pedro", "nickName": "mascara sagrada", "age": 29 } ]
Como ven al momento de ejecutar la aplicación Spring boot detectó que usamos H2 y que existe un archivo llamado data.sql y ejecutó ese archivo en nuestra base de datos en memoria, esto permitió que nuestro servicio contara con datos desde el principio sin necesidad de cargar ningún valor en la base de datos manualmente.
En siguientes posts explicaremos como ejecutar transacciones y manejarlas utilizando H2 o cualquier otra base de datos.
Para enterarte sobre futuros posts te recomendamos seguirnos en nuestras redes sociales: https://twitter.com/devs4j y https://www.facebook.com/devs4j/.
Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com