作者:掩飾獨殇_389 | 来源:互联网 | 2023-06-03 10:05
在SpringBoot的架构中,DataSourceInitializer类可以在项目启动后初始化数据,我们可以通过自动执行自定义sql脚本初始化数据,下面这篇文章主要给大家介绍了
说明:所有的代码基于SpringBoot 2.0.3版本
背景
在应用程序启动后,可以自动执行建库、建表等SQL脚本.下文中以要自动化执行people.sql脚本为例说明,脚本在SpringBoot工程中的路径为:classpath:people.sql,脚本的具体内容如下:
CREATE TABLE IF NOT EXISTS people(
persion_id BIGINT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20),
last_name VARCHAR(20),
PRIMARY KEY (persion_id)
);
实现核心
在SpringBoot的架构中,DataSourceInitializer类可以实现自动执行脚本的功能。通过自定义DataSourceInitializer Bean就可以实现按照业务要求执行特定的脚本。
实现方法
- 前提
已经构建了DataSource Bean。
- 方法
通过@Configuration、@Bean和@Value三个注解实现自定义DataSourceInitializer Bean,现在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;
@Configuration
public class BatchTaskDataSourceInitializer {
/**
* 构建Resource对象
*/
@Value("classpath:schema-all.sql")
private Resource businessScript;
/**
* 自定义Bean实现业务的特殊需求
* @param dataSource
* @return
*/
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
// 设置数据源
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScripts(businessScript);
return populator;
}
}
注意
有两点需要说明下:
- db文件夹下的脚本可能有多个,所以,这里要使用PathMatchingResourcePatternResolver,读取多个.sql的文件;
- 获取文件的路径是classpath*:script/db/*.sql,classpath后加个星号,意思是连jar包中的符合该规则的文件,都可以获取到,因为该项目最终会打成jar包来运行,如果不使用这个星号,就会出现在开发的时,没有问题,等到了测试或生产环境,就会出现找不到sql文件问题。当然,这里的文件规则,需要自己定义好,不要扫到了本不应加载的其他包中的文件了。
总结
说明:所有的代码基于SpringBoot 2.0.3版本
背景
在应用程序启动后,可以自动执行建库、建表等SQL脚本.下文中以要自动化执行people.sql脚本为例说明,脚本在SpringBoot工程中的路径为:classpath:people.sql,脚本的具体内容如下:
CREATE TABLE IF NOT EXISTS people(
persion_id BIGINT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(20),
last_name VARCHAR(20),
PRIMARY KEY (persion_id)
);
实现核心
在SpringBoot的架构中,DataSourceInitializer类可以实现自动执行脚本的功能。通过自定义DataSourceInitializer Bean就可以实现按照业务要求执行特定的脚本。
实现方法
- 前提
已经构建了DataSource Bean。
- 方法
通过@Configuration、@Bean和@Value三个注解实现自定义DataSourceInitializer Bean,现在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;
@Configuration
public class BatchTaskDataSourceInitializer {
/**
* 构建Resource对象
*/
@Value("classpath:schema-all.sql")
private Resource businessScript;
/**
* 自定义Bean实现业务的特殊需求
* @param dataSource
* @return
*/
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
// 设置数据源
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator());
return initializer;
}
private DatabasePopulator databasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScripts(businessScript);
return populator;
}
}
注意
有两点需要说明下:
- db文件夹下的脚本可能有多个,所以,这里要使用PathMatchingResourcePatternResolver,读取多个.sql的文件;
- 获取文件的路径是classpath*:script/db/*.sql,classpath后加个星号,意思是连jar包中的符合该规则的文件,都可以获取到,因为该项目最终会打成jar包来运行,如果不使用这个星号,就会出现在开发的时,没有问题,等到了测试或生产环境,就会出现找不到sql文件问题。当然,这里的文件规则,需要自己定义好,不要扫到了本不应加载的其他包中的文件了。
总结