[英]Spring Boot MySQL Database Initialization Error with Stored Procedures
在 Spring Boot 应用程序中,我试图在运行集成测试之前初始化一些 MySQL 数据库表和存储过程,方法是按照文档中的建议将 schema.sql 文件放在我的资源目录中。
create table 语句有效,但 create procedure 语句抛出异常。 导致异常的示例 schema.sql 文件语句如下所示:
DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()
BEGIN
SELECT * from `database`.employees;
END;
问题是;
存储过程中的字符被 Spring ScriptUtils class 解析出来,它在执行之前解析 schema.sql 文件,然后导致 MySQL 在脚本上抛出语法错误。
我查看了ScriptUtils class,但未能找到逃避;
的方法。 字符与程序。 使用\\
和\
作为转义字符也不起作用,MySQL DELIMITER
命令也是如此。
有没有人能够使用带有 Spring Boot 的 schema.sql 文件创建 MySQL 存储过程? 如果可以,他们可以举个例子吗?
有关一些其他信息,以下Spring JIRA 问题解决了相同的主题,但已关闭,无法修复label。
答案非常简单。 Spring Boot 有一个 DataSource 分隔符属性,可以在 application.properties 文件中设置:
spring.datasource.separator=^;
然后在schema.sql文件中全部;
不在存储过程中的语句需要使用新的分隔符进行更新。
DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()
BEGIN
SELECT * from `database`.employees;
END ^;
添加到@Andrews 答案:
当使用不是由 Spring Boot 自动创建的自定义dataSource
,可能会发生没有使用spring.datasource.separator
属性的情况。 在这种情况下,分隔符不会转发到Populator
。 在这种情况下,它可以直接在数据源初始化中设置。 例如,假设dataSource
在其他地方定义,则可以在特殊更新配置文件中使用以下内容:
<jdbc:initialize-database data-source="dataSource" enabled="${initDatabase:false}" separator="^;">
<jdbc:script location="${update.schema.script}" />
</jdbc:initialize-database>
或者,当显式声明填充器时:
<bean id="dbPopulator" class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
<property name="separator" value="^;"/>
<property name="scripts">
<list>
<value>${update.schema.script}</value>
</list>
</property>
</bean>
<bean id="initDatabase" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="databasePopulator">
<ref bean="dbPopulator"/>
</property>
<!-- The same can be done for the cleaner: -->
<!-- <property name="databaseCleaner"><ref bean="dbCleanup"/></property> -->
</bean>
如果有人像我一样使用 spring-boot + testcontainers 进入这个线程,可以省略分隔符,因为 testcontainers 的解析器知道程序 synthax(尽管仍然不适用于 MS-SQL)。 所以原始脚本将起作用:
DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()
BEGIN
SELECT * from `database`.employees;
END;
如果使用注释进行测试,那么您可以执行以下操作:
@Sql(
scripts = "/myTestSQL.sql",
config = @SqlConfig(separator = "^;")
)
@Test
void mySQLTest() {
// my test logic
}
鉴于myTestSQL.sql
存储在测试resources
文件夹中。 此外,只有不同的过程或查询才能用^;
, 过程中的内容仍然应该用;
分开 ,就像在https://stackoverflow.com/a/35871322/2092109回答
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.