一个数据库可以使用不同的方式进行初始化,这取决于你的技术栈。或者你可以手动完成该任务,只要数据库是单独的过程。
JPA有个生成DDL的特性,并且可以设置为在数据库启动时运行,这可以通过两个外部属性进行控制:
spring.jpa.generate-ddl
(boolean
)控制该特性的关闭和开启,跟实现者没关系。spring.jpa.hibernate.ddl-auto
(enum
)是一个Hibernate特性,用于更细力度的控制该行为,更多详情参考以下内容。你可以显式设置spring.jpa.hibernate.ddl-auto
,标准的Hibernate属性值有none
,validate
,update
,create
,create-drop
。Spring Boot根据你的数据库是否为内嵌数据库来选择相应的默认值,如果是内嵌型的则默认值为create-drop
,否则为none
。通过查看Connection
类型可以检查是否为内嵌型数据库,hsqldb,h2和derby是内嵌的,其他都不是。当从内存数据库迁移到一个真正的数据库时,你需要当心,在新的平台中不能对数据库表和数据是否存在进行臆断,你也需要显式设置ddl-auto
,或使用其他机制初始化数据库。
此外,启动时处于classpath根目录下的import.sql
文件会被执行。这在demos或测试时很有用,但在生产环境中你可能不期望这样。这是Hibernate的特性,和Spring没有一点关系。
Spring JDBC有一个初始化DataSource
特性,Spring Boot默认启用该特性,并从标准的位置schema.sql
和data.sql
(位于classpath根目录)加载SQL。此外,Spring Boot将加载schema-${platform}.sql
和data-${platform}.sql
文件(如果存在),在这里platform
是spring.datasource.platform
的值,比如,你可以将它设置为数据库的供应商名称(hsqldb
, h2
, oracle
, mysql
, postgresql
等)。Spring Boot默认启用Spring JDBC初始化快速失败特性,所以如果脚本导致异常产生,那应用程序将启动失败。脚本的位置可以通过设置spring.datasource.schema
和spring.datasource.data
来改变,如果设置spring.datasource.initialize=false
则哪个位置都不会被处理。
你可以设置spring.datasource.continue-on-error=true
禁用快速失败特性。一旦应用程序成熟并被部署了很多次,那该设置就很有用,因为脚本可以充当"可怜人的迁移"-例如,插入失败时意味着数据已经存在,也就没必要阻止应用继续运行。
如果你想要在一个JPA应用中使用schema.sql
,那如果Hibernate试图创建相同的表,ddl-auto=create-drop
将导致错误产生。为了避免那些错误,可以将ddl-auto
设置为“”(推荐)或none
。不管是否使用ddl-auto=create-drop
,你总可以使用data.sql
初始化新数据。
如果你正在使用Spring Batch,那么它会为大多数的流行数据库平台预装SQL初始化脚本。Spring Boot会检测你的数据库类型,并默认执行那些脚本,在这种情况下将关闭快速失败特性(错误被记录但不会阻止应用启动)。这是因为那些脚本是可信任的,通常不会包含bugs,所以错误会被忽略掉,并且对错误的忽略可以让脚本具有幂等性。你可以使用spring.batch.initializer.enabled=false
显式关闭初始化功能。
Spring Boot支持两种高级数据迁移工具Flyway(基于SQL)和Liquibase(XML)。
想要在启动时自动运行Flyway数据库迁移,需要将org.flywaydb:flyway-core
添加到你的classpath下。
迁移是一些V<VERSION>__<NAME>.sql
格式的脚本(<VERSION>
是一个下划线分割的版本号,比如'1'或'2_1')。默认情况下,它们存放在classpath:db/migration
文件夹中,但你可以使用flyway.locations
(一个列表)改变它。详情可参考flyway-core中的Flyway
类,查看一些可用的配置,比如schemas。Spring Boot在FlywayProperties中提供了一个小的属性集,可用于禁止迁移,或关闭位置检测。Spring Boot将调用Flyway.migrate()
执行数据库迁移,如果想要更多控制可提供一个实现FlywayMigrationStrategy的@Bean
。
默认情况下,Flyway将自动注入(@Primary
)DataSource
到你的上下文,并用它进行数据迁移。如果想使用不同的DataSource
,你可以创建一个,并将它标记为@FlywayDataSource
的@Bean
-如果你这样做了,且想要两个数据源,记得创建另一个并将它标记为@Primary
,或者你可以通过在外部配置文件中设置flyway.[url,user,password]
来使用Flyway的原生DataSource
。
这是一个Flyway示例,你可以作为参考。
想要在启动时自动运行Liquibase数据库迁移,你需要将org.liquibase:liquibase-core
添加到classpath下。
你可以使用liquibase.change-log
设置master变化日志位置,默认从db/changelog/db.changelog-master.yaml
读取。除了YAML,Liquibase还支持JSON, XML和SQL改变日志格式。查看LiquibaseProperties获取可用配置,比如上下文,默认schema等。
这里有个Liquibase示例可作为参考。