我正在尝试为单元测试创建MariaDB数据库,并希望使用Spring的ScriptUtils
来执行带有表和testdata转储的SQL文件。当我使用HeidiSQL创建转储时,它会将包含代码的注释插入到生成的sql文件中,如下所示,在加载转储时禁用外键检查:
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
当我通过HeidiSQL执行转储脚本时,一切都很顺利。但是在Java中使用以下函数:
@BeforeClass
public static void initializeForTest() throws Exception {
context = new ClassPathXmlApplicationContext("Beans.xml");
dsRoot = (DataSource) context.getBean("dataSourceRoot");
ScriptUtils.executeSqlScript(dsRoot.getConnection(), new ClassPathResource("DROP_AND_CREATE_DATABASE.sql"));
}
导致抛出异常,因为外键约束失败,因为转储创建了一些表,其中包含对仍然必须创建的表的外键引用。例如:
CREATE TABLE `cities` (
`postal_code` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`country_alpha2` varchar(2) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`postal_code`,`country_alpha2`),
KEY `country_alpha2` (`country_alpha2`),
CONSTRAINT `cities_ibfk_1` FOREIGN KEY (`country_alpha2`) REFERENCES `countries` (`alpha2`)
);
/* ... */
CREATE TABLE `countries` (
`code` int(3) NOT NULL,
`alpha2` varchar(2) COLLATE utf8_unicode_ci DEFAULT NULL,
`alpha3` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL,
`langCS` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langDE` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langEN` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langES` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langFR` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langIT` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`langNL` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`code`),
UNIQUE KEY `alpha2` (`alpha2`),
UNIQUE KEY `alpha3` (`alpha3`)
);
我可以以某种方式执行脚本而不会忽略包含代码的注释吗?
答案 0 :(得分:1)
ScriptUtils JavaDoc最有用的javadoc是其中一个
splitSqlScript(
EncodedResource resource,
String script,
String separator,
String commentPrefix,
String blockCommentStartDelimiter,
String blockCommentEndDelimiter,
List<String> statements)` method, because it explains the meaning of the parameters:
将SQL脚本拆分为由提供的分隔的单独语句 分隔符串。每个单独的声明都将添加到 提供{@code List}。
在脚本中,所提供的{@code commentPrefix}将受到尊重: 任何以注释前缀开头并延伸到结尾的文本 该行将从输出中省略。
同样,提供 {@code blockCommentStartDelimiter}和{@code blockCommentEndDelimiter}分隔符将被尊重:任何文本 封闭在块注释中将从输出中省略。
此外,将折叠多个相邻的空白字符 进入一个空间。 ...
因此,在第二次查看util后,您将找到方法:
public static void executeSqlScript(
Connection connection,
EncodedResource resource,
boolean continueOnError,
boolean ignoreFailedDrops,
String commentPrefix,
String separator,
String blockCommentStartDelimiter,
String blockCommentEndDelimiter)
它接缝你不能禁用块注释删除funktion,但你可以配置它使用其他块注释分隔符:
所以我认为诀窍是使用一个不同或根本不存在的blockCommentStartDelimiter
。
ScriptUtils.executeSqlScript(
dsRoot.getConnection(), //Connection connection,
new EncodedResource(new ClassPathResource("DROP_AND_CREATE_DATABASE.sql")), //EncodedResource resource,
false, //boolean continueOnError,
false, //boolean ignoreFailedDrops,
"--", //String commentPrefix,
";", //String separator,
"##/*", //String blockCommentStartDelimiter,
"*/##"); //String blockCommentEndDelimiter)
BTW:其他解决方法:改为通过查找和替换更改所有评论:在开头添加set foreign_key_checks = 0;
,在结尾添加set foreign_key_checks = 1;
。
答案 1 :(得分:0)
我们最近在ScriptUtils正在执行的SQL查询中使用Oracle提示时遇到了类似的问题。
使用上面建议的“假”分隔符解决了它,但它似乎是一个应该在ScriptUtils本身修复的问题。
我在https://jira.spring.io/browse/DATAJDBC-88
打开了一张JIRA票感谢。