Spring Boot「06」Loading initial data
开发过程中,在对某些服务进行单元测试时离不开对数据库的依赖。此时,我们在测试时需要使用内存数据库搭配建表、插表语句来为服务提供基本的测试数据。今天,我们将来看一下 Spring Boot 中如何在启动时创建、并加载初始数据。
01-初始化数据库的方式
使用 JPA
spring.jpa.generate-ddl=true|false
属性来控制是否开启 DDL 生成使用 Hibernate
spring.jpa.hibernate.ddl-auto=none|validate|update|create|create-drop
属性来控制使用 Hibernate 初始化数据库时的行为。在使用内存数据库(例如 h2/hsqldb/derby)时,该属性存在一个默认值:未检测到 schema manager 时,默认值为 create-drop;其他情况,默认值为 none。当上述属性值为 create 或 crate-drop 时,Hibernate 在启动时还会读取 classpath 根目录下的 import.sql 并执行(不过注意:这是 Hibernate 的特性,并非 Spring 的)。使用 SQL Scripts
Spring Boot 会加载 classpath 根目录下的 schema.sql 和 data.sql;
spring.sql.init.platform=platform_value
属性可以使 Spring Boot 加载 schema-{platform_value}.sql,其中 platform_value 可以是 mysql/oracle/h2 等等;默认情况下,只有在使用内存数据库时,Spring Boot 才会加载上述的 SQL Scripts,这个行为可以通过属性
spring.sql.init.mode=always|never|embedded
来控制:always 指使用任何数据库时都初始化数据库,never 指从不初始化数据库,embedded 指使用内存数据库时初始化数据库;默认情况下,Spring Boot 执行 SQL Scripts 时是 fail-fast 的,这个行为可以通过属性
spring.sql.init.continue-on-error=true|false
调整;默认情况下,使用 SQL Scripts 初始化数据库发生在 JPA EntityManagerFactory Bean 创建之前。尽管不推荐方式 1-3 中的多种初始化方式混合使用,但是如果想在 Hibernate 自动生成 DDL 的基础上再执行 schema.sql 和 data.sql,可以将属性
spring.jpa.defer-datasource-initialization
设置为 true。意味着将 SQL Scripts 的执行事件延迟(defer)到 EntityManagerFactory Bean 创建之后。schema.sql 可以在 Hibernate 生成的 DDL 基础上做额外的动作,data.sql 可以用来填充数序。
spring.jpa.hibernate.ddl-auto
不同取值的含义:
create,如果表格已存在,则先删除,然后创建新的表格;
update,修改已存在的 schema,并不会删除任何表或列,即使它们不再被应用使用;
create-drop,与 create 类似,只不过在所有操作都完成以后,会删掉数据库,一般用于 unit test
validate,仅验证表和列是否存在;若不存在,则抛异常;
none,指不开启 DDL 自动生成
02-内存数据库 H2
接下来,我们用上节中介绍的第 2、3 种方法,搭配 H2 数据库,演示一下 Spring Boot 是如何初始化数据库的。首先,在 pom.xml 中引入 h2 和 spring-boot-starter-data-jpa 依赖:
接下来,在 application.properties 中配置内存数据库。
jdbc:h2:mem:testdb
指使用内存数据库(易失),数据库名为 testdb。如果需要将数据库持久化在磁盘上,可以将mem:testdb
修改为file:/data/file/path
。然后,创建一个 Entity 类 Country,它存储在 COUNTRY 表中。
接下来,我们先只使用 Hibernate(即上节中的第 2 种方法)来自动生成数据库表。开启自动生成功能,需要在 application.properties 中增加 spring.jpa.hibernate.ddl-auto=create-drop
。到目前为止,运行程序就会在内存数据库中创建 COUNTRY 表。Hibernate 会使用 org.hibernate.SQL logger 打印建表语句,如果要从日志中看到,需要在 application.properties 中增加debug=true
,如下所示:
为了方便查询 h2 数据库的状态,我们打开 H2 内置的 GUI 控制台,只需要在 application.properties 中添加spring.h2.console.enabled=true
。然后就可以通过浏览器访问 http://localhost:8080/h2-console,如下所示:
输入之前配置的数据库连接信息即可登录。
配置完成后,我们将上节中介绍的 SQL Scripts(即第 3 种方法)在 Hibernate 生成的 schema 基础上再通过 schema.sql 和 data.sql 完成数据库的初始化。首先,我们需要在 application.properties 中添加spring.jpa.defer-datasource-initialization=true
,表示我们将 SQL Scripts 的初始化延迟到 Hibernate 之后。然后,在 resources 下添加 schema.sql:
再添加 data.sql,向创建的表格中插入 5 条数据:
好了,到此为止,所有的准备工作就都完成啦。让我们来运行下程序,看看效果吧。登录到 h2-console 之后,使用select * from country;
查询 data.sql 中的数据有没有插入到数据库中,结果如下所示:
[1] Spring Boot With H2 Database
03-总结
今天,我们学习了 Spring Boot 中加载初始化数据的三种方式,并且以 Hibernate + SQL Scripts 配合的方式,搭配 H2 内存数据库,演示了整个过程。这种加载初始化数据的方式在做的单元测试是非常有用,可以提高测试效率。
版权声明: 本文为 InfoQ 作者【Samson】的原创文章。
原文链接:【http://xie.infoq.cn/article/021a6f723d2fc518e7b9f3e75】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论