使用DBUnit迁移数据库

作者:    |       Hibernate ORM

在过去的几周里,我不得不迁移一个MySQL数据库,结果比我想的要复杂。过去我使用过MySQL自带的一些工具,例如mysqldump及其各种选项。但在最近的迁移中,这竟然出奇地...不可行。

第一次迁移是将拉丁MySQL数据库迁移到UTF编码数据库。默认情况下,MySQL和JDBC驱动程序都使用拉丁编码(或者从系统字符集派生),所以如果你想让你数据库使用UTF8,例如,使中国用户能够存储他们的数据,你最好确保你的数据库使用UTF8。我建议你按表为基础进行,如果你使用Hibernate导出模式,这很容易,只需在你的方言中添加一个扩展。同时,确保你在JDBC连接字符串中设置characterEncoding=UTF-8以正确初始化SQL会话。注意,对于MySQL 5.x,不需要设置useUnicode=true切换。

我遇到的问题是seamframework.org生产数据库,一年前创建时是拉丁编码。我一直推迟迁移,因为我们从来没有遇到过任何问题,并且使用mysqldumprecode对我无效(如果你想尝试,这里有相关说明)。

我正在考虑的第二次迁移是从MySQL迁移到PostgreSQL,用于开发和测试。现在,许多人使用mysqldump为此,然后调整它的许多命令行选项和开关(让它兼容ANSI SQL,该死!)然后闭上眼睛祈祷,当将转储导入Postgres时。然而,在我的情况下,这并没有奏效,因为mysqldump导出类型列作为原始二进制。你不能导出像truefalse或者您可以导入到Postgres中的任何内容布尔型类型。这里的问题实际上是MySQL(就像强大的Oracle一样)不支持真正的布尔型数据类型,并且Hibernate默认为创建一个java.lang.Boolean映射的列。回顾过去,Hibernate可能不应该在MySQL上这样做,出于可移植性的原因,应使用tinyint(1)映射 - 另一方面,如果您始终留在MySQL上,这也是可以的。

所以mysqldump两种情况都不起作用,我不得不寻找另一种解决方案。我用DBUnit和一个简单的20行类解决了它

import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.operation.DatabaseOperation;

import java.sql.Connection;
import java.sql.DriverManager;

public class Migration {

    public static final String[] TABLES = new String[]{ "FOO", "BAR", "BAZ" };

    public static void main(String[] args) throws Exception {
        System.out.println("Running Migration...");

        Class.forName("com.mysql.jdbc.Driver");
        //Class.forName("org.postgresql.Driver");

        Connection exportConnection = DriverManager.getConnection(
            "jdbc:mysql://127.0.0.1/mydb", 
            "johndoe", 
            "secret"
        );
        IDatabaseConnection exportDatabaseConnection = new DatabaseConnection(exportConnection);

        Connection importConnection = DriverManager.getConnection(
            "jdbc:mysql://127.0.0.1/mytarget?characterEncoding=UTF-8&sessionVariables=FOREIGN_KEY_CHECKS=0", 
            "johndoe", 
            "secret"
        );
        IDatabaseConnection importDatabaseConnection = new DatabaseConnection(importConnection);

        for (String table : TABLES) {
        System.out.println("Migrating table: " + table);
            QueryDataSet exportDataSet = new QueryDataSet(exportDatabaseConnection);
            exportDataSet.addTable(table, "SELECT * FROM " + table);
            DatabaseOperation.INSERT.execute(importDatabaseConnection, exportDataSet);
        }

        exportDatabaseConnection.close();
        importDatabaseConnection.close();
        System.out.println("Migration complete");

    }
}

这是我从MySQL拉丁迁移到MySQL UTF编码所使用的代码。对于PostgreSQL迁移,取消注释驱动程序并使用不同的导入JDBC URL。确保您禁用了导入SQL会话的外键检查,因为您不知道或无法控制表和行导出和导入的顺序。


返回顶部