可以使用不同的方式初始化SQL数据库,具体取决于堆栈是什么。当然,如果数据库是一个单独的过程,您也可以手动执行。建议使用单一机制来生成模式。
10.1. 使用JPA初始化数据库
JPA具有用于DDL生成的功能,可以将其设置为在启动时针对数据库运行。这是通过两个外部属性控制的:
spring.jpa.generate-ddl
(布尔值)打开和关闭该功能,并且与供应商无关。spring.jpa.hibernate.ddl-auto
(枚举)是一种Hibernate功能,可以更精细地控制行为。此功能将在本指南的后面部分详细介绍。
10.2. 使用Hibernate初始化数据库
您可以设置spring.jpa.hibernate.ddl-auto
明确和标准的Hibernate属性值none
,validate
,update
,create
,和create-drop
。Spring Boot根据是否认为您的数据库已嵌入为您选择默认值。默认为create-drop
是否未检测到任何模式管理器或none
在所有其他情况下。通过查看Connection
类型和JDBC URL,可以检测到嵌入式数据库。hsqldb
,h2
和derby
是候选人,其他人则不是。从内存数据库切换到“真实”数据库时,请不要对新平台中表和数据的存在做出假设。您必须ddl-auto
显式设置或使用其他机制之一来初始化数据库。
您可以通过启用org.hibernate.SQL 记录器来输出架构创建。如果启用调试模式,此操作将自动为您完成。 |
|
---|---|
另外,import.sql
如果Hibernate从头开始创建模式(即,如果ddl-auto
属性设置为create
或create-drop
),则在启动时将执行在类路径的根目录中命名的文件。如果您小心的话,这对于演示和测试很有用,但可能不希望出现在生产环境的类路径中。这是Hibernate的功能(与Spring无关)。
10.3. 使用基本SQL脚本初始化数据库
Spring Boot可以自动创建您的架构(DDL脚本)DataSource
并对其进行初始化(DML脚本)。它分别从标准根类路径位置schema.sql
和加载SQL data.sql
。另外,Spring Boot处理schema-${platform}.sql
和data-${platform}.sql
文件(如果存在),其中platform
的值为spring.datasource.platform
。这使您可以在必要时切换到特定于数据库的脚本。例如,您可以选择将其设置为数据库中的供应商名称(hsqldb
,h2
,oracle
,mysql
,postgresql
,等)。
当仅使用基本的SQL脚本时,Spring Boot会自动创建Embedded的架构DataSource 。可以使用该spring.datasource.initialization-mode 属性来自定义此行为。例如,如果您要始终初始化,则DataSource 无论其类型如何:spring.datasource.initialization-mode =总是在基于JPA的应用程序中,您可以选择让Hibernate创建架构或使用schema.sql ,但您不能两者都做。spring.jpa.hibernate.ddl-auto 如果使用,请确保禁用schema.sql 。spring.jpa.hibernate.ddl-auto =无如果使用的是Flyway或Liquibase等高级数据库迁移工具,则应单独使用它们来创建和初始化架构。不建议与Flyway或Liquibase一起使用基本脚本schema.sql 和data.sql 脚本,并且在以后的版本中将删除支持。 |
|
---|---|
默认情况下,Spring Boot启用Spring JDBC初始化程序的快速失败功能。这意味着,如果脚本导致异常,则应用程序将无法启动。您可以通过设置来调整行为spring.datasource.continue-on-error
。
10.4. 使用R2DBC初始化数据库
如果您使用的是R2DBC,则常规DataSource
自动配置会后退,因此不能使用上述任何选项。
您可以在启动时使用SQL脚本初始化数据库,如以下示例所示:
@Configuration(proxyBeanMethods = false)
static class DatabaseInitializationConfiguration {
@Autowired
void initializeDatabase(ConnectionFactory connectionFactory) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource[] scripts = new Resource[] { resourceLoader.getResource("classpath:schema.sql"),
resourceLoader.getResource("classpath:data.sql") };
new ResourceDatabasePopulator(scripts).populate(connectionFactory).block();
}
}
另外,您也可以配置迁飞或Liquibase配置DataSource
为您办理迁移的持续时间。这两个库均提供用于设置的属性url
,username
以及password
要迁移的数据库的属性。
选择此选项时,org.springframework:spring-jdbc 仍然是必需的依赖项。 |
|
---|---|
10.5. 初始化一个Spring Batch数据库
如果您使用Spring Batch,则它随大多数流行的数据库平台一起预包装了SQL初始化脚本。Spring Boot可以检测数据库类型并在启动时执行这些脚本。如果您使用嵌入式数据库,则默认情况下会发生这种情况。您还可以为任何数据库类型启用它,如以下示例所示:
物产
Yaml
spring.batch.initialize-schema=always
您还可以通过设置spring.batch.initialize-schema
为显式关闭初始化never
。
10.6. 使用更高级别的数据库迁移工具
春天引导支持两种更高级别的迁移工具:迁飞和Liquibase。
10.6.1. 在启动时执行Flyway数据库迁移
要在启动时自动运行Flyway数据库迁移,请将添加org.flywaydb:flyway-core
到您的类路径中。
通常,迁移是采用以下形式的脚本V<VERSION>__<NAME>.sql
(带有<VERSION>
下划线分隔的版本,例如“ 1”或“ 2_1”)。默认情况下,它们位于名为的目录中classpath:db/migration
,但是您可以通过设置修改该位置spring.flyway.locations
。这是一个或多个classpath:
或多个filesystem:
位置的逗号分隔列表。例如,以下配置将在默认类路径位置和/opt/migration
目录中搜索脚本:
物产
Yaml
spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration
您也可以添加特殊的{vendor}
占位符以使用特定于供应商的脚本。假设以下内容:
物产
Yaml
spring.flyway.locations=classpath:db/migration/{vendor}
db/migration
前面的配置不是使用,而是根据数据库的类型(例如,db/migration/mysql
对于MySQL)设置要使用的目录。支持的数据库列表在中提供DatabaseDriver
。
迁移也可以用Java编写。Flyway将使用任何实现的bean自动配置JavaMigration
。FlywayProperties
提供Flyway的大多数设置以及少量的其他属性,这些属性可用于禁用迁移或关闭位置检查。如果需要对配置进行更多控制,请考虑注册FlywayConfigurationCustomizer
Bean。
Spring Boot调用Flyway.migrate()
以执行数据库迁移。如果您想要更多控制,请提供@Bean
实现FlywayMigrationStrategy
。
Flyway支持SQL和Java回调。要使用基于SQL的回调,请将回调脚本放置在classpath:db/migration
目录中。要使用基于Java的回调,请创建一个或多个实现的bean Callback
。任何此类bean都会自动向进行注册Flyway
。可以通过使用@Order
或实现来订购它们Ordered
。FlywayCallback
也可以检测到实现了不推荐使用的接口的Bean ,但是不能与Callback
Bean一起使用。
默认情况下,Flyway自动在您的上下文中自动连接(@Primary
)DataSource
并将其用于迁移。如果您想使用其他名称DataSource
,则可以创建一个并将其标记@Bean
为@FlywayDataSource
。如果这样做并想要两个数据源,请记住创建另一个数据源并将其标记为@Primary
。另外,您可以DataSource
通过设置spring.flyway.[url,user,password]
外部属性来使用Flyway的本机。设置spring.flyway.url
或spring.flyway.user
足以使Flyway使用其自己的DataSource
。如果未设置这三个属性中的任何一个,spring.datasource
则将使用其等效属性的值。
您还可以使用Flyway为特定情况提供数据。例如,您可以放入特定于测试的迁移,src/test/resources
并且仅在您的应用程序开始进行测试时才运行它们。此外,您可以使用特定于配置文件的配置进行自定义,spring.flyway.locations
以便仅在特定配置文件处于活动状态时才运行某些迁移。例如,在中application-dev.properties
,您可以指定以下设置:
物产
Yaml
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
使用该设置,dev/db/migration
仅在dev
配置文件处于活动状态时才运行迁移。
10.6.2. 在启动时执行Liquibase数据库迁移
要在启动时自动运行Liquibase数据库迁移,请将添加org.liquibase:liquibase-core
到您的类路径中。
org.liquibase:liquibase-core 将_添加到类路径时,默认情况下,在应用程序启动期间和测试运行之前都将运行数据库迁移。可以通过使用spring.liquibase.enabled 属性来自定义行为,并在main 和test 配置中设置不同的值。不可能使用两种不同的方式来初始化数据库(例如,Liquibase用于应用程序启动,JPA用于测试运行)。 |
|
---|---|
默认情况下,从中读取主更改日志db/changelog/db.changelog-master.yaml
,但是您可以通过设置来更改位置spring.liquibase.change-log
。除了YAML,Liquibase还支持JSON,XML和SQL更改日志格式。
默认情况下,Liquibase自动在您的上下文中自动连接(@Primary
)DataSource
并将其用于迁移。如果需要使用其他名称DataSource
,则可以创建一个并将其标记@Bean
为@LiquibaseDataSource
。如果这样做,并且想要两个数据源,请记住创建另一个数据源并将其标记为@Primary
。另外,您可以DataSource
通过设置spring.liquibase.[url,user,password]
外部属性来使用Liquibase的本机。设置spring.liquibase.url
或spring.liquibase.user
足以使Liquibase使用其自己的DataSource
。如果未设置这三个属性中的任何一个,spring.datasource
则将使用其等效属性的值。
请参阅LiquibaseProperties
以获取有关可用设置的详细信息,例如上下文,默认架构和其他。