( 三十一 )、 SpringBoot项目启动自动执行sql脚本
( 三十一 )、 SpringBoot项目启动自动执行sql脚本
方式一:在配置文件中配置相关属性
1、关键属性:
1、spring.datasource.schema:
- 表初始化语句,默认加载schema.sql,看getScripts源码,它还会加载schema-${platform}.sql文件,其中platform就是spring.datasource.platform的值指定DDL脚本文件
2、spring.datasource.data:
- 数据初始化,默认加载data.sql,还会加载data-${platform}.sql文件,指定 DQL(数据查询)脚本或DML(数据操作)脚本 文件, 一般都是数据插入脚本文件
3、spring.datasource.platform:
为了支持不同数据库platform属性的默认值是’all’,所以当有在不同数据库切换的情况下才使用all配置,因为默认值的情况下,spring boot会自动检测当前使用的数据库。
4、spring.datasource.initialization-mode:
- 初始化模式(springboot2.0),其中有三个值:
- always为始终执行初始化
- embedded只初始化内存数据库(默认值),如h2等
- never为不执行初始化
- 在SpringBoot1.x中,不需要配置便可之间运行
- 在SpringBoot 2.x 版本中,默认值是embedded,所以必须配置为 always
5、spring.datasource.separator
- 默认为 ;,自定义存储过程或者函数时,可能需要使用delimiter设置断句分隔符,但是delimiter在springboot执行的sql脚本里不可用。springboot提供了spring.datasource.separator配置解决这个问题,如上配置之后,不必执行delimiter $$$,我们在脚本里可以直接使用$$$作为分隔符。
其他属性:
spring.datasouce.data-password
spring.datasouce.data-username
spring.datasouce.schema-password
spring.datasouce.schema-username
这四个值为执行schema.sql或者data.sql时,用的用户
2、yml配置示例:
spring:
datasource:
schema:
- classpath:sql/schema.sql
- classpath:sql/procedure.sql
- classpath:sql/function.sql
data: classpath:sql/data.sql
initialization-mode: always
platform: mysql
separator: $$$ # 默认为 ;
方式二: 自定义DataSourceInitializer
在SpringBoot的架构中,DataSourceInitializer
类可以在项目启动后初始化数据,我们可以通过自动执行自定义sql脚本初始化数据。通过自定义DataSourceInitializer
Bean就可以实现按照业务要求执行特定的脚本。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import javax.sql.DataSource;
/**
* @ClassName CustomizeDataSourceInitializer
* @Description: TODO
* @Author guoshihua
* @Date 2020/5/5 0005 下午 3:47
* @Version V1.0
* @See 版权声明
**/
@Configuration
public class CustomizeDataSourceInitializer {
@Value("classpath:sql/schema.sql")
private Resource sqlScriptSchema;
@Value("classpath:sql/data.sql")
private Resource sqlScriptData;
@Value("classpath:sql/procedure.sql")
private Resource sqlScriptProcedure;
@Value("classpath:sql/function.sql")
private Resource sqlScriptFunction;
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource){
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
dataSourceInitializer.setDatabasePopulator(databasePopulator());
return dataSourceInitializer;
}
private DatabasePopulator databasePopulator(){
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(sqlScriptSchema);
populator.addScript(sqlScriptData);
populator.addScript(sqlScriptProcedure);
populator.addScript(sqlScriptFunction);
populator.setSeparator("$$$"); // 分隔符,默认为;
return populator;
}
}
3、不同运行环境执行不同脚本
一般情况下,都会有多个运行环境,比如开发、测试、生产等。而不同运行环境通常需要执行的sql会有所不同。为解决这个问题,可以使用通配符来实现。
创建不同环境的文件夹
在 resources 文件夹创建不同环境对应的文件夹,如dev/、test/、prod/。
配置 : application.yml
spring:
datasource:
schema: classpath:${spring.profiles.active:dev}/schema.sql
data: classpath:${spring.profiles.active:dev}/data.sql
initialization-mode: always
platform: mysql
separator: $$$ # 默认为 ;
注:\${}通配符支持缺省值。如上面的配置中的`${spring.profiles.active:dev}`,其中分号前是取属性spring.profiles.active的值,而当该属性的值不存在,则使用分号后面的值,即dev。