2

我正在开发一个项目,该项目使用不同的 MySQL 模式进行客户管理,例如,每个客户都有自己的数据库模式,该模式是使用骨架模板创建的。

对于兼容性问题,我必须从 Java 创建新的 MySQL 模式,这在 PHP 之前已经完成。我创建了一个小型服务类,它通过重复使用在 MySQL 数据库上完美运行CREATE TABLE 'a' LIKE 'b';,但是这不适用于 H2db,因为 H2LIKE在创建表时不支持 -part。然后我创建了一个 MySQL 并修改了文件以便使用 Java 轻松处理(Files.readAllLines输入到 中Statement.executeBatch)。但是,此转储在 H2db 上也因COLLATION=UTF8. 遗憾的是,拥有这些很重要,因为我们经常有需要正确编码的特殊字符,因此不建议简单地从 sql 文件中删除所述语句。

我像这样初始化 DataSource:

public DataSource dataSource(ResourceLoader resourceLoader) {
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .setScriptEncoding("UTF-8")
            .addScript("data.sql").build();
}

所以,我的配置可能性很少。我们gradle用来构建我们的应用程序,所以建议的maven-plugin 也无济于事 - 至少我还没有发现如何将它与 一起使用gradle,如果可能的话。

所以我的问题是,我需要检查服务是否真的正确地保存了数据,但我不能在内存中做,因为 H2 不支持语法,我不允许使用“真正的”MySQL数据库,因为我们所有的测试都必须从“真实”连接中分离出来,并且如果有必要,只能使用数据库的内存存储。

4

3 回答 3

5

我最终使用https://github.com/vorburger/MariaDB4j作为嵌入式数据库,因为无论如何我们都使用 MariaDB,所以这肯定会消除所有方言问题。由于这与嵌入式 MongoDB 的有效工作方式相同,因此额外的测试成本是可以接受的。

不过需要注意的是:这需要64 位操作系统才能工作。

于 2016-11-18T11:23:00.143 回答
1

你使用 MySQL。你有几种可能性。

我使用的几个:

1.使用凹槽(插件)在gradle中创建您为mysql测试创建新数据库,并以相同的方式创建模式。

gradle 中的一些配置可以帮助您。

def dbUser = 'root'
def dbPasswd = 'root'
def dbHost = 'localhost'
def dbName = 'testDB'
def dbPort = '3306'
def dbUrl = 'jdbc:mysql:////localhost:3306/testDB?
useUnicode=yes&characterEncoding=UTF-8'

dependencies { 
        testCompile files('libs/junit-4.12.jar')
        testCompile files('libs/hamcrest-core-1.3.jar')
        testCompile files('libs/mysql-connector-java-5.1.29.jar')
       }

//create DB for test
task loadDriver {
    URLClassLoader loader = GroovyObject.class.classLoader
    loader.addURL(file('libs/mysql-connector-java-5.1.29.jar').toURL())
    java.sql.DriverManager.registerDriver(loader.loadClass('com.mysql.jdbc.Driver').newInstance())
}

task createTestData(dependsOn: loadDriver) {

//  println 'Connecting to database ...'
//  def sql = groovy.sql.Sql.newInstance('jdbc:mysql://localhost:3306/?useUnicode=yes&characterEncoding=UTF-8', dbUser, dbPasswd, 'com.mysql.jdbc.Driver')
//  println '... connected'

//    println 'Drop test database testDB...'
//    sql.execute 'drop database IF exists testDB;'
//    println 'database testDB is droped'

//    println 'Create test database testDB...'
//    sql.execute 'create database if not exists testDB'
//    println 'Database testDB is created'

}

2.您可以在 java 中以类似的方式创建您在测试中使用的基类来创建 testDB mysql 例如:

public class TestDAO {
@Before
public void setUp() throws ClassNotFoundException, SQLException {

    java.util.Date date = new java.util.Date();
    LOG.info("Set up database for test "+date.getTime());
    database = database + date.getTime();
    LOG.info("DATABASE NAME:"+database);


    LOG.info("Create database:"+database);
    try {
        Class.forName(JDBC_DRIVER);
        conn = DriverManager.getConnection(URL+":"+PORT, USER, PASS);
        stmt = conn.createStatement();
        String sql = "CREATE DATABASE " + database;
        stmt.executeUpdate(sql);
    } finally {
        if (stmt != null)
            stmt.close();
        if (conn != null)
            conn.close();
    }

人们还可以发明其他一些方法。

于 2016-10-27T16:05:30.453 回答
1

数据库迁移工具

使用数据库迁移工具构建并重新构建您的数据库模式,例如:

无需直接编辑数据库,而是编写 SQL 脚本和/或 Java JDBC 类来定义数据库模式。创建表、定义列、导入数据、插入预期的行,所有这些都在 SQL 或 Java 中作为 SQL 脚本和/或 Java 类的集合。在测试时,这些工具中的任何一个都将通过执行您不断增长的脚本/类集合作为指令来创建和加载一个新的数据库。测试后,删除数据库。

用于此目的的 Java 类可以酌情使用特定于 MySQL 或 H2 的替代语法。

在生产中使用 H2

此外,您可以完全跳过 MySQL,并在生产中使用 H2。

您可以通过为每个客户提供自己单独的 H2 数据库来解决多租户问题,这意味着每个客户都有自己的物理数据文件。

上面提到的数据库迁移工具通过在数据库中创建一个带有版本信息的额外表来工作。部署应用程序时,应用程序首先运行迁移工具以更新数据库结构和数据,并始终保持最新状态。这使得在生产中拥有许多单独的数据库变得很容易,每个数据库在下次使用时在生产中自动更新。

您的数据库服务器上需要足够的内存来支持尽可能多的多个数据库,这些数据库可能同时打开并由 H2 使用。对于大量租户,您可以运行多个数据库服务器,每个服务器都包含租户数据库的一个子集。

有关详细信息,请参阅一个 JVM 中的多个独立 H2 数据库

于 2016-10-27T21:48:34.863 回答