On this page
85. Database Initialization
可以使用不同的方式初始化 SQL 数据库,具体取决于堆栈是什么。当然,如果数据库是一个单独的过程,您也可以手动执行。
85.1 使用 JPA 初始化数据库
JPA 具有用于 DDL 生成的功能,可以将其设置为在启动时针对数据库运行。这是通过两个外部属性控制的:
spring.jpa.generate-ddl
(布尔值)打开和关闭该功能,并且与供应商无关。spring.jpa.hibernate.ddl-auto
(枚举)是一种 Hibernate 功能,可以更精细地控制行为。此功能将在本指南的后面部分详细介绍。
85.2 使用 Hibernate 初始化数据库
您可以显式设置spring.jpa.hibernate.ddl-auto
,并且标准的 Hibernate 属性值为none
,validate
,update
,create
和create-drop
。 Spring Boot 根据是否认为您的数据库已嵌入为您选择默认值。如果未检测到任何模式 Management 器,则默认为create-drop
,否则为none
。通过查看Connection
类型,可以检测到嵌入式数据库。嵌入了hsqldb
,h2
和derby
,其他未嵌入。从内存数据库转换为“实际”数据库时,请不要对新平台中表和数据的存在做出假设。您必须显式设置ddl-auto
或使用其他机制之一来初始化数据库。
Note
您可以通过启用org.hibernate.SQL
Logger 来输出架构创建。如果启用debug mode,则会自动为您完成此操作。
另外,如果 Hibernate 从头开始创建架构(即ddl-auto
属性设置为create
或create-drop
),则在启动时将在 Classpath 的根目录中执行名为import.sql
的文件。如果您小心的话,这对于演示和测试很有用,但是您可能不想在生产环境的 Classpath 中使用它。这是一个 Hibernate 功能(与 Spring 无关)。
85.3 初始化数据库
Spring Boot 可以自动创建DataSource
的架构(DDL 脚本)并对其进行初始化(DML 脚本)。它从标准根 Classpath 位置:schema.sql
和data.sql
加载 SQL。另外,Spring Boot 处理schema-${platform}.sql
和data-${platform}.sql
文件(如果存在),其中platform
是spring.datasource.platform
的值。这使您可以在必要时切换到特定于数据库的脚本。例如,您可以选择将其设置为数据库的供应商名称(hsqldb
,h2
,oracle
,mysql
,postgresql
等)。
Note
Spring Boot 自动创建嵌入式DataSource
的架构。可以使用spring.datasource.initialization-mode
属性来自定义此行为。例如,如果要始终初始化DataSource
而不考虑其类型:
spring.datasource.initialization-mode=always
默认情况下,Spring Boot 启用 Spring JDBC 初始化程序的快速失败功能。这意味着,如果脚本导致异常,则应用程序将无法启动。您可以通过设置spring.datasource.continue-on-error
来调整行为。
Note
在基于 JPA 的应用程序中,您可以选择让 Hibernate 创建架构或使用schema.sql
,但是您不能两者都做。如果使用schema.sql
,请确保禁用spring.jpa.hibernate.ddl-auto
。
85.4 初始化 Spring Batch 数据库
如果您使用 Spring Batch,则它随大多数流行的数据库平台一起预包装了 SQL 初始化脚本。 Spring Boot 可以检测数据库类型并在启动时执行这些脚本。如果您使用嵌入式数据库,则默认情况下会发生这种情况。您还可以为任何数据库类型启用它,如以下示例所示:
spring.batch.initialize-schema=always
您还可以通过设置spring.batch.initialize-schema=never
显式关闭初始化。
85.5 使用更高级别的数据库迁移工具
Spring Boot 支持两个更高级别的迁移工具:Flyway和Liquibase。
85.5.1 在启动时执行 Flyway 数据库迁移
要在启动时自动运行 Flyway 数据库迁移,请将org.flywaydb:flyway-core
添加到您的 Classpath 中。
迁移是格式为V<VERSION>__<NAME>.sql
(带有<VERSION>
下划线分隔的版本,例如“ 1”或“ 2_1”)的脚本。默认情况下,它们位于名为classpath:db/migration
的文件夹中,但是您可以通过设置spring.flyway.locations
来修改该位置。这是一个或多个classpath:
或filesystem:
位置的逗号分隔列表。例如,以下配置将在默认 Classpath 位置和/opt/migration
目录中搜索脚本:
spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration
您还可以添加特殊的{vendor}
占位符以使用特定于供应商的脚本。假设以下内容:
spring.flyway.locations=classpath:db/migration/{vendor}
前面的配置没有使用db/migration
,而是根据数据库的类型(例如db/migration/mysql
表示 MySQL)来设置要使用的文件夹。 DatabaseDriver中提供了受支持的数据库列表。
FlywayProperties提供了 Flyway 的大多数设置以及少量的其他属性,可用于禁用迁移或关闭位置检查。如果需要对配置进行更多控制,请考虑注册FlywayConfigurationCustomizer
bean。
Spring Boot 调用Flyway.migrate()
来执行数据库迁移。如果您想要更多控制权,请提供实现FlywayMigrationStrategy的@Bean
。
Flyway 支持 SQL 和 Java callbacks。要使用基于 SQL 的回调,请将回调脚本放在classpath:db/migration
文件夹中。要使用基于 Java 的回调,请创建一个或多个实现Callback
的 bean。任何此类 bean 都会自动通过Flyway
注册。可以使用@Order
或实现Ordered
对其进行排序。也可以检测到实现不推荐使用的FlywayCallback
接口的 Bean,但是不能与Callback
Bean 一起使用。
默认情况下,Flyway 自动在您的上下文中自动连接(@Primary
)DataSource
并将其用于迁移。如果您想使用其他DataSource
,则可以创建一个并将其@Bean
标记为@FlywayDataSource
。如果这样做并想要两个数据源,请记住创建另一个数据源并将其标记为@Primary
。另外,您可以通过在外部属性中设置spring.flyway.[url,user,password]
来使用 Flyway 的本机DataSource
。设置spring.flyway.url
或spring.flyway.user
足以使 Flyway 使用其自己的DataSource
。如果未设置这三个属性中的任何一个,则将使用其等效的spring.datasource
属性的值。
有一个Flyway sample,以便您可以了解如何进行设置。
您还可以使用 Flyway 为特定情况提供数据。例如,您可以将特定于测试的迁移放在src/test/resources
中,并且仅在您的应用程序开始进行测试时才运行它们。另外,您可以使用特定于配置文件的配置来自定义spring.flyway.locations
,以便仅在特定配置文件处于 Active 状态时才运行某些迁移。例如,在application-dev.properties
中,您可以指定以下设置:
spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
使用该设置,只有在dev
配置文件处于 Active 状态时,才能在dev/db/migration
中进行迁移。
85.5.2 在启动时执行 Liquibase 数据库迁移
要在启动时自动运行 Liquibase 数据库迁移,请将org.liquibase:liquibase-core
添加到您的 Classpath 中。
默认情况下,从db/changelog/db.changelog-master.yaml
读取主更改日志,但是您可以通过设置spring.liquibase.change-log
来更改位置。除了 YAML,Liquibase 还支持 JSON,XML 和 SQL 更改日志格式。
默认情况下,Liquibase 在您的上下文中自动装配(@Primary
)DataSource
并将其用于迁移。如果需要使用其他DataSource
,则可以创建一个@Bean
并将其标记为@LiquibaseDataSource
。如果这样做,并且想要两个数据源,请记住创建另一个数据源并将其标记为@Primary
。另外,您可以通过在外部属性中设置spring.liquibase.[url,user,password]
来使用 Liquibase 的本机DataSource
。设置spring.liquibase.url
或spring.liquibase.user
足以使 Liquibase 使用其自己的DataSource
。如果未设置这三个属性中的任何一个,则将使用其等效的spring.datasource
属性的值。
有关可用设置(例如上下文,默认架构等)的详细信息,请参见LiquibaseProperties。
有一个Liquibase sample,以便您可以了解如何进行设置。