Spring的ScriptUtils忽略了dump中包含注释的代码

时间:2015-10-15 09:23:07

标签: java mysql spring mariadb spring-jdbc

我正在尝试为单元测试创​​建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`)
);

我可以以某种方式执行脚本而不会忽略包含代码的注释吗?

2 个答案:

答案 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票

感谢。