2

私は、顧客管理にさまざまな MySQL スキーマを使用するプロジェクトに取り組んでいます。たとえば、すべての顧客は、スケルトン テンプレートで作成された独自のデータベース スキーマを持っています。

互換性の問題のため、Java から新しい MySQL スキーマを作成する必要がありますが、これは以前は PHP で行われていました。を繰り返し使用して MySQL データベースで完全に機能する小さなサービス クラスを作成しましたがCREATE TABLE 'a' LIKE 'b';、H2 はテーブルを作成するときに - 部分をサポートしていないため、これは H2db では機能しませんLIKE。次に、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

とにかくMariaDBを使用しているため、https://github.com/vorburger/MariaDB4jを埋め込みデータベースとして使用することになりました。これにより、すべての方言の問題が確実に解消されます。これは組み込み MongoDB と同じように効果的に機能するため、テストのための追加コストは許容されます。

ただし注意点: これが動作するには 64 ビット OS が必要です。

于 2016-11-18T11:23:00.143 に答える
1

データベース移行ツール

次のようなデータベース移行ツールを使用して、データベース スキーマを構築および再構築します。

データベースを直接編集する代わりに、SQL スクリプトや Java JDBC クラスを記述して、データベース スキーマを定義します。テーブルの作成、列の定義、データのインポート、予想される行の挿入をすべて、SQL スクリプトや Java クラスのコレクションとして SQL または Java で行います。テスト時に、これらのツールのいずれかが、増え続けるスクリプト/クラスのコレクションを命令として実行することにより、新しいデータベースを作成してロードします。テスト後、データベースを削除します。

この目的のための Java クラスは、必要に応じて MySQL または H2 に固有の代替構文を使用できます。

本番環境で H2 を使用する

また、MySQL を完全にスキップして、本番環境で H2 を使用することもできます。

各顧客に独自の個別の H2 データベースを提供することで、マルチテナンシーの問題を解決できます。これは、各顧客が独自の物理データ ファイルを持つことを意味します。

上記のデータベース移行ツールは、バージョン管理情報を使用して、データベースに追加のテーブルを作成することによって機能します。アプリをデプロイするとき、アプリは最初に移行ツールを実行してデータベース構造とデータを最初に更新し、常に最新の状態に保ちます。これにより、運用環境に多数の個別のデータベースを簡単に配置でき、それぞれが次回の使用時に運用環境で自動的に更新されます。

H2 で同時に開いて使用する可能性のある複数のデータベースをサポートするには、データベース サーバーに十分なメモリが必要です。非常に多数のテナントの場合、それぞれがテナントのデータベースのサブセットを持つ複数のデータベース サーバーを実行できます。

詳細については、1 つの JVM 内の複数の独立した H2 データベースを参照してください。

于 2016-10-27T21:48:34.863 に答える
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 に答える