SpringBoot:项目在启动时如何执行指定sql文件

SpringBoot:项目在启动时如何执行指定sql文件

在SpringBoot项目中,当有在项目启动时先执行指定的sql语句的需求时,可以在resources文件夹下添加需要执行的sql文件,文件中的sql语句可以是DDL(数据定义)脚本或DML(数据操作),DQL(数据查询)脚本,然后在application.properties或application.yml配置加入相应的配置即可,如下:

# schema.sql中一般存放的是DDL脚本
spring.datasource.schema = classpath:schema.sql 

# data.sql中一般存放的是DQL(数据查询)脚本或DML(数据操作)脚本
spring.datasource.data =  classpath:data.sql
spring:
  datasource:
    schema: classpath:schema.sql 
    data: classpath:data.sql 

如果需要执行多个SQL文件,可以进行如下配置:

# schema.sql中一般存放的是DDL脚本
spring.datasource.schema = classpath:schema_1.sql ,schema_2.sql

# data.sql中一般存放的是DQL(数据查询)脚本或DML(数据操作)脚本
spring.datasource.data =  classpath:data_1.sql ,data_2.sql
spring:
  datasource:
    schema: classpath:schema_1.sql ,schema_2.sql
    data: classpath:data_1.sql ,data_2.sql
spring:
  datasource:
    schema: 
    	- classpath:schema_1.sql 
    	- classpath:schema_2.sql
    data: classpath:
    	- classpath:data_1.sql 
    	- classpath:data_2.sql

注意:当在执行的sql文件中存在存储过程或函数时(例如如下脚本),在启动项目时会报错。

-- 当存储过程`p`存在时,删除。
drop procedure if exists p;

-- 创建存储过程`p`
create procedure p() 
begin
  declare row_num int;
  select count(*) into row_num from `t_user`;
  if row_num = 0 then
    INSERT INTO `t_user`(`username`, `password`) VALUES ('zhangsan', '123456');
  end if;
end;

-- 调用存储过程`p`
call p();
drop procedure if exists p;

报错原因如下:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'create procedure p() begin declare row_num int' at line 1

因为SpringBoot在解析sql脚本时,默认是以’;'作为断句的分隔符的。即:SpringBoot把’create procedure p() begin declare row_num int’当成是一条普通的sql语句。而我们需要的是创建一个存储过程。

解决方案:

  1. 修改sql脚本的断句分隔符。如:spring.datasource.separator=$$$。
  2. 修改SQL语句:
-- 当存储过程`p`存在时,删除。
drop procedure if exists p1;$$$

-- 创建存储过程`p`
create procedure p() 
begin
  declare row_num int;
  select count(*) into row_num from `t_user`;
  if row_num = 0 then
    INSERT INTO `t_user`(`username`, `password`) VALUES ('zhangsan', '123456');
  end if;
end;$$$

-- 调用存储过程`p`
call p();$$$
drop procedure if exists p;$$$

因为SQL脚本的断句分隔符从“;”变成“ $ $ $ ”,所以可能需要在SQL语句的“;”后加“ $ $ $ ”,不然可能会出现将整个脚本当成一条sql语句来执行的情况。

©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页