java - Spring 的 ScriptUtils 忽略转储中包含注释的代码

标签 java mysql spring mariadb spring-jdbc

我正在尝试为单元测试创​​建一个 MariaDB 数据库,并希望使用 Spring 的 ScriptUtils 来执行包含表和测试数据转储的 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`)
);

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

最佳答案

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:

Split an SQL script into separate statements delimited by the provided separator string. Each individual statement will be added to the provided {@code List}.

Within the script, the provided {@code commentPrefix} will be honored: any text beginning with the comment prefix and extending to the end of the line will be omitted from the output.

Similarly, the provided {@code blockCommentStartDelimiter} and {@code blockCommentEndDelimiter} delimiters will be honored: any text enclosed in a block comment will be omitted from the output.

In addition, multiple adjacent whitespace characters will be collapsed into a single space. ...

所以再看一下 util,您会发现方法:

public static void executeSqlScript(
      Connection connection,
      EncodedResource resource,
      boolean continueOnError,
      boolean ignoreFailedDrops,
      String commentPrefix,
      String separator,
      String blockCommentStartDelimiter,
      String blockCommentEndDelimiter)

您不能禁用 block 注释删除功能,但您可以将其配置为使用其他 block 注释分隔符: 所以我认为诀窍是使用一个不同的或根本不发生的 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)

顺便说一句:其他解决方法:通过查找和替换更改所有注释:在开头添加 set foreign_key_checks = 0; 并在 set foreign_key_checks = 1;结束。

关于java - Spring 的 ScriptUtils 忽略转储中包含注释的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33144628/

相关文章:

eclipse - 将我现有的 Spring APP 移动到 HTTPS

java - 在 j2ee 应用程序中为 isbn 编号建模的正确方法

C# 如何使 foreach 循环不覆盖字符串变量

java - 系统跳过 Hibernate 映射注释

php - 使用jquery ajax从MySQL检索多个数据

PHP:用于登录的 Cookie

java - 如何修复Spring-boot应用程序中的错误 'java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver'?

java - 膨胀 android.support.v7.widget.CardView 抛出错误

java - Swing 中的 Round Double 值

java - 为什么我会得到这个异常(exception)?