[英]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.