SpringBoot启动执行sql脚本的3种方法实例
目录
- 背景
- 配置application.yml文件
- 自定义DataSourceInitializer Bean
- 启动时执行方法
- Springboot自动执行sql文件
- 总结
背景
项目里后端需要计算坐标距离,想用sql实现算法,然后通过执行一个sql脚本,创建一个函数供各业务调用。我们需要在springboot项目启动时执行sql脚本,在网上一顿搜索,总结了有三种做法:
- 配置application.yml文件
- 自定义DataSourceInitializer Bean
- 启动时执行方法
第一种做法最方便简洁,是首选方案,但是由于种种原因项目里不能用,只能选择使用第二种做法。第三种做法不推荐,这里只当是记录一下做过的工作。
开发调测sql脚本的时候,推荐使用这个驱动,可以让我们看到sql执行日志,有没有执行?报了什么异常?
spring datasource driver-class-name: net.sf.log4jdbc.DriverSpy
<dependency> <groupId>com.googlecode.log4jdbc</groupId> <artifactId>log4jdbc</artifactId> <version>1.2</version> <scope>runtime</scope> </dependency>
同时,spring.datasource.url的配置应该如下起头
spring datasource url: 'jdbc:log4jdbc:mysql://XXXXX'
配置application.yml文件
spring: datasource: username: root password: root driver-class-name: net.sf.log4jdbc.DriverSpy url: jdbc:log4jdbc:mysql://localhost:3306/springboot schema: - classpath:sql/function.sql - classpath:sql/procedure.sql initialization-mode: ALWAYS separator:\\
自定义存储过程或者函数时,可能需要使用delimiter设置断句分隔符,但是delimiter在springboot执行的sql脚本里不可用。springboot提供了spring.datasource.separator配置解决这个问题,如上配置之后,不必执行delimiter \\,我们在脚本里可以直接使用\\作为分隔符。
以下两种情况会导致启动时sql脚本不执行:
1.启动类上的注解如果配置了exclude={DataSourceAutoConfiguration.class},sql脚本将不被执行。
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
2.如果开启了druid连接池的防火墙,sql脚本将不被执行。
spring datasource druid filter wall enabled: true
自定义DataSourceInitializer Bean
参考博文:Spring Boot中自动执行sql脚本
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; 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; public class CustomizeDataSourceInitializer { @Value("classpath:sql/function.sql") private Resource functionScript; @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(functionScript); populator.setSeparator("$$"); return populator; } }
populator.setSeparator("$$")的作用和配置spring.datasource.separator一样。
启动时执行方法
参考博文:springboot启动前执行方法的几种方式
三种实现方式:
第一种 @PostConstruct注解
第二种 实现InitializingBean接口
第三种 实现BeanPostProcessor接口
这种做法思路就是启动时调用MyBatis接口,但是受限于Mybatis的用法规则,不能完美的满足需求,比如,执行的sql脚本只能有一条语句,这样的话,如果我要创建两个存储过程,需要先后调用两个MyBatis接口。我们不必这么做,前两种做法更好。
Springboot自动执行sql文件
在springboot1.5及以前的版本,要执行sql文件只需在applicaion文件里指定sql文件的位置即可。但是到了springboot2.x版本,
如果只是这样做的话springboot不会自动执行sql文件,还需在applicaion文件里加入如下配置
initialization-mode: always
这样springboot就会帮我们自动执行sql了
注意:!!!
建表完成后如果不再需要使用sql文件的话要把sql文件删除,否则springboot会重新建表,这样原来表中的内容就没有了!!!
总结
到此这篇关于SpringBoot启动执行sql脚本的3种方法的文章就介绍到这了,更多相关SpringBoot启动执行sql脚本内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!