java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot启动执行sql脚本

SpringBoot启动执行sql脚本的3种方法实例

作者:AtongWood

在应用程序启动后,可以自动执行建库、建表等SQL脚本,下面这篇文章主要给大家介绍了关于SpringBoot启动执行sql脚本的3种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

背景

项目里后端需要计算坐标距离,想用sql实现算法,然后通过执行一个sql脚本,创建一个函数供各业务调用。我们需要在springboot项目启动时执行sql脚本,在网上一顿搜索,总结了有三种做法:

第一种做法最方便简洁,是首选方案,但是由于种种原因项目里不能用,只能选择使用第二种做法。第三种做法不推荐,这里只当是记录一下做过的工作。

开发调测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脚本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文