( 三十一 )、 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),其中有三个值:
  1. always为始终执行初始化
  2. embedded只初始化内存数据库(默认值),如h2等
  3. never为不执行初始化
  4. 在SpringBoot1.x中,不需要配置便可之间运行
  5. 在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。

 

posted @ 2021-10-24 10:31  邓维-java  阅读(2092)  评论(0编辑  收藏  举报