Carga inicial en Spring Boot
Una de las necesidades que nos encontramos muchas veces es popular nuestra base de datos con algún Script inicial. Por ese motivo vamos a mostrar como realizar carga inicial en Spring Boot al arrancar la aplicación.
Aunque existen algunas herramientas para mantener un histórico y hacer carga inicial de datos, como puede ser flyway, en esta entrada nos vamos a centrar en las facilidades que nos da Spring Boot para poder crear una carga inicial de datos sql y creación de tablas en una base de datos. Para ello nos apoyaremos en Spring Data para realizar las conexiones con nuestra base de datos, poder realizar la persistencia y creación automática de las tablas.
Además si queremos eliminar la automatización y realizar de manera manual carga de datos y creación de tablas veremos como usar dos tipos de ficheros, data.sql y schema.sql.
Uso de Schema.sql
Aunque cuando trabajamos con Spring Data podemos delegar en el framework la creación de nuestras tablas a través de la anotación @Entity, si queremos evitar esa automatización podemos hacer uso de un fichero que se llame schema.sql. Este fichero deberá ir dentro de la carpeta resources y será cargado al arrancar la aplicación.
En el caso en el que usemos esta opción habrá que desactivar la creación automática de las tablas en nuestro fichero de propiedades:
spring.jpa.hibernate.ddl-auto=none
CREATE TABLE car ( id INTEGER NOT NULL AUTO_INCREMENT, brand VARCHAR(128) NOT NULL, model VARCHAR(128) NOT NULL, color VARCHAR(128), PRIMARY KEY (id) );
Uso de data.sql para la carga inicial en Spring Boot
Una vez que se ha creado la tabla, necesitaremos cargar datos en nuestra base de datos, para ello vamos a hacer uso de data.sql. Este fichero deberá estar dentro de la carpeta resources.
INSERT INTO car VALUES (1,'Ford', 'yellow', 'Mustang');
Creación de la base de datos con Hibernate
Spring a través de sus propiedades y de la dependencia de Spring Data:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
nos va a proporciona una propiedad que Hibernate usará para la generación de DDL, spring.jpa.hibernate.ddl-auto.
Esta propiedad podrá tener cinco valores:
- create – Con esta propiedad Hibernate hará primer un Drop, para a continuación crear las nuevas tablas o tabla.
- update – En este caso Hibernate nunca borrará las tablas o las columnas, simplemente actualizará el schema si hay algún cambio.
- create-drop – Esta opción es la típica que usaremos en test, lo que hará será crear al principio y borrar la base de datos una vez hemos realizado todas las operaciones.
- validate – En Esta opción se valida y tablas y columnas existen, en el caso en el que no exisan se lanza una excepción.
- none – Con esta opción desactivamos la generación DDL, por ejemplo si queremos, crear a manos las tablas.
Spring Boot elegirá un valor por defecto en función de si la base de datos esta embebida con create-drop o none sino lo está.
Anotación @Sql
Cuando creamos nuestros test tendremos una batería de datos de prueba los cuales vamos a querer cargar o crear sus tablas, para esos casos haremos uso de @Sql. Esta anotación la podemos usar a nivel de clase o de método.
@SpringBootTest @Sql({"/schema_test.sql","/test_cars.sql"}) public class CarServiceIntegrationTest { @Autowired private CarRepository carRepository; @Test public void testFindAll() { assertEquals(1, carRepository.findAll().size()); } }
Existen diferentes atributos que podemos usar con la anotación @SQL que nos facilitará el trabajo sobre todo en nuestra parte de testing:
- config – configuración local para los scripts. Este atributo irá acompañado de una anotación propia @SqlConfig, que indicará si aplica la configuración de manera local.
- executionPhase – establecemos cuando ejecutar los scripts, antes o después del método: BEFORE_TEST_METHOD or AFTER_TEST_METHOD
- statements – este atributo nos permitirá ejecutar sentencias SQL.
- scripts – el path del script SQL.
O como hemos indicado lo podemos establecer a nivel de método:
@Test @Sql({"/schema_test.sql","/test_cars.sql"}) public void testFindAll() { assertEquals(1, carRepository.findAll().size()); }
Como hemos visto uno de los atributos que podemos aplicar a nuestra anotación @SQL es config, el cual nos ayudará para nuestra configuración en local, vamos verlo con un ejemplo.
@Test @Sql(scripts = {"/test_cars.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED)) public void testLoadDataForTestCase() { assertEquals(1, carRepository.findAll().size()); }
Como podemos ver en el ejemplo anterior @SqlConfig nos va a ayudar establecer una serie de propiedades para ese test en concreto, como por ejemplo el encoding y el modo de transacción.
Conclusión
En este artículo sobre la Carga inicial en Spring Boot, hemos visto diferentes maneras de cargar datos de manera inicial haciendo uso de los ficheros schema.sql y data.sql y de la anotación @Sql.
Tal y como hemos comentado al principio existen herramientas mucho más avanzadas y óptimas para realizar este tipo de carga de datos como Flyway.
Si quieres echar un vistazo al código y a un test funcionando puedes echar un vistazo en nuestro github.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!