( 三十一 )、 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。