Java DBUnit 有没有办法自动创建表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1531324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:53:40  来源:igfitidea点击:

Is there any way for DBUnit to automatically create tables?

javadatasetcreate-tabledbunit

提问by neu242

I just realized that DBUnit doesn't create tables by itself (see How do I test with DBUnit with plain JDBC and HSQLDB without facing a NoSuchTableException?).

我刚刚意识到 DBUnit 不会自己创建表(请参阅如何使用普通 JDBC 和 HSQLDB 测试 DBUnit 而不会遇到 NoSuchTableException?)。

Is there any way for DBUnit to automatically create tables from a dataset or dtd?

DBUnit 有没有办法从数据集或 dtd 自动创建表?

EDIT:For simple testing of an in-memory database like HSQLDB, a crude approach can be used to automatically create tables:

编辑:对于像 HSQLDB 这样的内存数据库的简单测试,可以使用一种粗略的方法来自动创建表:

private void createHsqldbTables(IDataSet dataSet, Connection connection) throws DataSetException, SQLException {
    String[] tableNames = dataSet.getTableNames();

    String sql = "";
    for (String tableName : tableNames) {
      ITable table = dataSet.getTable(tableName);
      ITableMetaData metadata = table.getTableMetaData();
      Column[] columns = metadata.getColumns();

      sql += "create table " + tableName + "( ";
      boolean first = true;
      for (Column column : columns) {
        if (!first) {
          sql += ", ";
        }
        String columnName = column.getColumnName();
        String type = resolveType((String) table.getValue(0, columnName));
        sql += columnName + " " + type;
        if (first) {
          sql += " primary key";
          first = false;
        }
      }
      sql += "); ";
    }
    PreparedStatement pp = connection.prepareStatement(sql);
    pp.executeUpdate();
}

private String resolveType(String str) {
  try {
    if (new Double(str).toString().equals(str)) {
      return "double";
    }
    if (new Integer(str).toString().equals(str)) {
      return "int";
    }
  } catch (Exception e) {}

  return "varchar";
}

采纳答案by tpdi

Not really. As the answer you linked points out, the dbunit xml files contain data, but not column types.

并不真地。正如您链接的答案所指出的,dbunit xml 文件包含数据,但不包含列类型。

And you really don't want to do this;you risk polluting your database with test artifacts, opening up the possibility that production code will accidentally rely on tables created by the test process.

你真的不想这样做;您冒着使用测试工件污染数据库的风险,从而增加了生产代码意外依赖测试过程创建的表的可能性。

Needing to do this strongly suggests you don't have your db creation and maintenance process adequately defined and scripted.

需要这样做强烈建议您没有充分定义和编写数据库创建和维护过程。

回答by Michael Lloyd Lee mlk

No. You will have to execute an SQL script with the table definitions in.

不可以。您必须执行包含表定义的 SQL 脚本。

As I posted in the other thread, the XML does not contain enough data to create a table. I guess you could do something scary like parse the values to attempt to work out what values it contains but that would be quite brittle. This differs from Hibernate in that annotated classes do contain a lot of information on how the database looks. Part in annotations and part in the Java types fields have.

正如我在另一个线程中发布的那样,XML 没有包含足够的数据来创建表。我想你可以做一些可怕的事情,比如解析值来尝试找出它包含的值,但这会很脆弱。这与 Hibernate 的不同之处在于,带注释的类确实包含大量关于数据库外观的信息。部分注解和部分 Java 类型字段都有。

http://www.dbunit.org/faq.html#ddl

http://www.dbunit.org/faq.html#ddl

回答by Martin Klinke

If you are using JPA you can usually configure your JPA provider so that it creates/updates the tables on initialization.

如果您使用 JPA,您通常可以配置您的 JPA 提供程序,以便它在初始化时创建/更新表。

E.g. for hibernate, specify the property hibernate.hbm2ddl.autoand set its value to create-drop (should be fine for testing).

例如,对于 hibernate,指定属性hibernate.hbm2ddl.auto并将其值设置为 create-drop(应该可以用于测试)。

See also: Hibernate Documentation, Chapter 3 Configuration

另请参阅:Hibernate 文档,第 3 章配置

However, make sure that the JPA provider is the first to access the DB ;)

但是,请确保 JPA 提供程序是第一个访问数据库的人;)

回答by Joshua W

I just wanted to chime in and say that this was very helpful for me. I needed to connect to an Oracle database and export it to an XML file, then import it as a test HSQL database and access it with Hibernate. I used this code to create the tables before doing

我只是想插嘴说这对我很有帮助。我需要连接到 Oracle 数据库并将其导出为 XML 文件,然后将其作为测试 HSQL 数据库导入并使用 Hibernate 访问它。我在做之前使用此代码创建表

DatabaseOperation.CLEAN_INSERT.execute(conn, dataset);. 

A word of caution though, this code sets the first column of each table as the primary key, so be careful if you use relationship tables as you may get a "Primary key constraint violation" on import. Thanks for the code snippet!

需要注意的是,这段代码将每个表的第一列设置为主键,所以如果使用关系表要小心,因为在导入时可能会遇到“主键约束冲突”。感谢您的代码片段!

回答by Asa

Spring Boot/ Spring JDBC can initialize a database with plain JDBC.

Spring Boot/Spring JDBC 可以使用普通的 JDBC 初始化数据库。

Spring JDBC has a DataSource initializer feature. Spring Boot enables it by default and loads SQL from the standard locations schema.sqland data.sql(in the root of the classpath). In addition Spring Boot will load the schema-${platform}.sqland data-${platform}.sqlfiles (if present), where platform is the value of spring.datasource.platform, e.g. you might choose to set it to the vendor name of the database (hsqldb, h2, oracle, mysql, postgresql etc.).

Spring JDBC 具有 DataSource 初始值设定项功能。Spring Boot 默认启用它并从标准位置schema.sqldata.sql(在类路径的根目录中)加载 SQL 。此外,Spring Boot 将加载schema-${platform}.sqldata-${platform}.sql文件(如果存在),其中平台是 的值spring.datasource.platform,例如,您可以选择将其设置为数据库的供应商名称(hsqldb、h2、oracle、mysql、postgresql 等)。

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html