创建数据库表,如果它没有在Java中产品代码存在和JUnit的确认(Creating a datab

2019-07-30 22:33发布

我写在Java的数据库的程序,并希望创建一个表,如果它不存在。 我了解DatabaseMetaData.getTables()从如何检测SQL表的在Java中存在呢? 我试图使用它:

private boolean tableExists() throws SQLException {
    System.out.println("tableExists()");

    DatabaseMetaData dbmd = conn.getMetaData();
    ResultSet rs = dbmd.getTables(null, null, this.getTableName(), null);

    System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME"));

    return rs.getRow() == 1;
}

问题是, rs.getRow()总是返回0 ,该表已被创建后还是一样。 使用rs.getString("TABLE_NAME")抛出一个异常,说明该结果集是空的。

一个可能的解决方案,我认为是执行CREATE TABLE语句,并赶上抛出任何异常。 不过,我不喜欢使用异常我的程序的控制流的想法。

FWIW,我使用HSQLDB。 不过,我想编写Java代码独立于关系数据库管理系统引擎。 还有另一种方法使用DatabaseMetaData.getTables()做我想要什么? 或者是有一些其他的解决办法,以写我tableExists()方法?

添加:

使用这里给出的建议,我发现,似乎在我的生产代码的工作一个解决方案:

private void createTable() throws SQLException {
    String sqlCreate = "CREATE TABLE IF NOT EXISTS " + this.getTableName()
            + "  (brand           VARCHAR(10),"
            + "   year            INTEGER,"
            + "   number          INTEGER,"
            + "   value           INTEGER,"
            + "   card_count           INTEGER,"
            + "   player_name     VARCHAR(50),"
            + "   player_position VARCHAR(20))";

    Statement stmt = conn.createStatement();
    stmt.execute(sqlCreate);
}

现在我也写一个JUnit测试断言该表确实获得创建:

public void testConstructor() throws Exception {
    try (BaseballCardJDBCIO bcdb = new BaseballCardJDBCIO(this.url)) {
        String query = "SELECT count(*) FROM information_schema.system_tables WHERE table_name = '" + bcdb.getTableName() + "'";
        Connection conn = DriverManager.getConnection(this.url);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(query);
        Assert.assertTrue(rs.next());
        Assert.assertEquals(1, rs.getInt(1));
        Assert.assertFalse(rs.next());
    }
}

在此测试失败assertEquals()使用以下信息:

FAILED: expected: <1> but was: <0>

Answer 1:

我找到了解决办法似乎工作:

private void createTable() throws SQLException {
    String sqlCreate = "CREATE TABLE IF NOT EXISTS " + this.getTableName()
            + "  (brand           VARCHAR(10),"
            + "   year            INTEGER,"
            + "   number          INTEGER,"
            + "   value           INTEGER,"
            + "   card_count           INTEGER,"
            + "   player_name     VARCHAR(50),"
            + "   player_position VARCHAR(20))";

    Statement stmt = conn.createStatement();
    stmt.execute(sqlCreate);
}

我不得不放置IF NOT EXISTS在我的SQL语句的正确位置。



Answer 2:

ResultSet的Java文档定义:

一个结果对象维护指向其当前数据行的光标。 最初,光标定位在第一行之前。 下一个方法将光标移动到下一行,并且因为它当在ResultSet对象没有更多的行返回false,它可以在while循环中使用在结果集中进行迭代。

所以,你必须调用next()方法,否则getRow()将始终返回零光标定位在第一行之前。



Answer 3:

有建立在MySQL功能为你寻求: http://dev.mysql.com/doc/refman/5.0/en/create-table.html

简而言之:您只需将IF NOT EXISTS在你创建表的查询结束。

编辑:
有这样的不一般的方式。 大多数数据库有一个information_scheme表虽然,查询,以确定该信息可能是这样的:

SELECT count(*) FROM information_schema.system_tables WHERE table_schem = 'public' AND table_name = 'user';

这个工程使用SQLite,MySQL和mSQL的,MariaDB的和Postgres +可能很多人的。



Answer 4:

我不知道这是否会必然朝着自己的目标有所帮助,但是当我跑进使用Python和MySQL这个问题,我只是增加了一个“删除表”语句中的每个“CREATE TABLE”语句之前,这样只是自动运行脚本删除现有表,然后重建的每个表。 这可能不是你的工作需要,但它是一个解决方案,我发现成功的为我类似的问题。



文章来源: Creating a database table if it does not exist in Java production code and confirming in JUnit