Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Spring导入MySQL表定义转储;s资源数据库填充器_Java_Mysql_Spring - Fatal编程技术网

Java 使用Spring导入MySQL表定义转储;s资源数据库填充器

Java 使用Spring导入MySQL表定义转储;s资源数据库填充器,java,mysql,spring,Java,Mysql,Spring,我们有一个Spring测试执行监听器,它通过Spring的ResourceDatabasePopulator导入转储的MySQL表定义: public class DBSetupExecutionListener extends AbstractTestExecutionListener { ... @Override public synchronized void beforeTestClass(TestContext testContext) {

我们有一个Spring测试执行监听器,它通过Spring的
ResourceDatabasePopulator
导入转储的MySQL表定义:

public class DBSetupExecutionListener extends AbstractTestExecutionListener {
    ...

    @Override
    public synchronized void beforeTestClass(TestContext testContext) {
        ...
        // import the table definitions from a previously dumped file
        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
        populator.addScript(new ClassPathResource("some-table-definitions.sql"));
        populator.execute(dataSource);
        ...
    }

    ...
}
导入的MySQL转储文件如下所示(简化):

通过works导入转储时没有任何问题,ResourceDatabasePopulator忽略了预处理器指令,因此无法在创建实际引用表之前先创建引用表。更改表定义的顺序确实可以解决这个问题,但对于多个表来说有点繁琐,尤其是在将当前表定义转储到文件时


在我看来,导入转储的SQL表定义是一项非常常见的任务,我想我在这里做错了什么。有没有办法告诉
ResourceDatabasePopulator
遵守预处理指令,从而在执行脚本时防止外键检查?

我遵照@M.Deinum的建议,实现了自己版本的
ResourceDatabasePopulator
。由于成员的范围有限,并且没有任何getter来检索这些字段,很遗憾,原始
ResourceDatabasePopulator
实现中存在一些复制和粘贴。这个类绝对不是为支持子类化而设计的

下面是在我的用例中为我工作的当前解决方案。它并不完美,可能是针对MySQL语句定制的,但至少它完成了任务

导入java.io.BufferedReader;
导入java.io.IOException;
导入java.lang.invoke.MethodHandles;
导入java.util.ArrayList;
导入java.util.Iterator;
导入java.util.LinkedHashMap;
导入java.util.List;
导入java.util.ListIterator;
导入java.util.Map;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.core.io.ByteArrayResource;
导入org.springframework.core.io.Resource;
导入org.springframework.core.io.support.EncodedResource;
导入org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
导入org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
导入org.springframework.jdbc.datasource.init.ScriptUtils;
导入org.springframework.jdbc.datasource.init.UncategorizedScriptException;
导入org.springframework.util.StringUtils;
/**
*使用中定义的SQL脚本填充、初始化或清理数据库
*外部资源。
*
*此实现将通过删除注释和处理指令来清理给定脚本
*包含在脚本中,并基于中定义的外键执行表重新排序
*尽力而为。
*
*
    *
  • 调用{@link#addScript}添加单个SQL脚本位置。 *
  • 调用{@link#addScripts}添加多个SQL脚本位置。 *
  • 有关进一步的配置选项,请参阅此类中的setter方法。 *
  • 调用{@link#populate}或{@link#execute}初始化或清除 *使用配置的脚本创建数据库。 *
* *@作者基思·唐纳德 *@作者戴夫·赛尔 *@作者尤尔根·霍勒 *@作者Chris Beams *@作者奥利弗·吉尔克 *@作者萨姆·布兰宁 *@作者克里斯·鲍德温 *@作者Roman Vottner * *@自3.0以来 *@请参阅数据库populatorutils *@见ScriptUtils */ 公共类OrderedResourceDatabasePopulator扩展了ResourceDatabasePopulator{ 私有静态最终记录器LOG=LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); 受保护的字符串sqlScriptEncoding; /** *使用默认设置构造一个新的{@code orderesourcedatabasepopulator}。 */ 公共OrderedResourceDatabasePopulator(){ /*无操作*/ } /** *使用默认设置构造一个新的{@code orderesourcedatabasepopulator} *对于提供的脚本。 * *@param为要执行的脚本编写脚本,以初始化或清理数据库 *(从不{@code null}) */ 公共OrderedResourceDatabasePopulator(资源…脚本){ 这个(); setScripts(cleanResource(scripts)); } /** *使用提供的值构造一个新的{@code orderesourcedatabasepopulator}。 * *@param continueOnError标志,指示应记录SQL中的所有故障,但不记录原因 *失败 *@param ignoreFailedDrops标志,指示失败的SQL{@code DROP}语句可以被删除 *忽略 *@param sqlScriptEncoding提供的SQL脚本的编码;可以是{@code null}或 *空表示平台编码 *@param脚本要执行的脚本,用于初始化或清理数据库(从不{@code *空}) */ public OrderedResourceDatabasePopulator(布尔continueOnError、布尔ignoreFailedDrops、, 字符串sqlScriptEncoding,资源…脚本){ super(continueOnError、ignoreFailedDrops、sqlScriptEncoding、scripts); } /** *添加要执行的脚本以初始化或清理数据库。 * *@param script指向SQL脚本的路径(从不{@code null}) */ @凌驾 公共void addScript(资源脚本){ super.addScript(cleanResource(script)[0]); } /** *添加要执行的多个脚本以初始化或清理数据库。 * *@param为要执行的脚本编写脚本(从不{@code null}) */ @凌驾 公共无效添加脚本(资源…脚本){ super.addScripts(cleanResource(scripts)); } /** *设置要执行的脚本以初始化或清理数据库,替换以前的任何脚本 *添加了脚本。 * *@param为要执行的脚本编写脚本(从不{@code null}) */ @凌驾 公共void集合脚本(资源…脚本){ super.setScripts(cleanResource(scripts)); } /** *如果与平台编码不同,请指定已配置SQL脚本的编码。 *
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

DROP TABLE IF EXISTS `someTable`;

CREATE TABLE `someTable`(
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `other_table_id` bigint(20) NOT NULL,
   ...
   PRIMARY KEY (`id`)
   KEY `FK_OTHERTABLE_ID`(`other_table_id`),
   CONSTRAINT `FK_OTHERTABLE_ID` FOREIGN KEY (`other_table_id`) REFERENCES `otherTable`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `otherTable`;

CREATE TABLE `otherTable`(
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  ...
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

...

/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
@Override
public synchronized void beforeTestClass(TestContext testContext) {
    ...
    // import the table definitions from a previously dumped file
    ResourceDatabasePopulator populator = new OrderedResourceDatabasePopulator();
    populator.addScript(new ClassPathResource("some-table-definitions.sql"));
    populator.execute(dataSource);
    ...
}