1

我在单元测试中使用 Apache Derby 10.9.x 和 Hibernate Entitymanager 4.1.9.Final。Derby db 模式是从 JPA 注释实体生成的。只有一个 persistence.xml 配置文件。我想在单元测试期间/之前/之后转储生成的 Derby db 模式。这样做的程序化方式是什么?

解决方案:

    // should not be required because Hibernate already started Derby:
    //Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();

    try (Connection conn = DriverManager.getConnection ("jdbc:derby:memory:unit-testing;")) {
        String cat = null;
        String schema = "ROOT";

        DatabaseMetaData md = conn.getMetaData();
        ResultSet rs = md.getTableTypes();
        ResultSetUtils.dump(rs);
        rs = md.getTables(cat, schema, null, new String[]{"TABLE"});
        ResultSetUtils.dump(rs);
        rs = md.getColumns(cat, schema, null, null);
        ResultSetUtils.dump(rs);
    }

公共类 ResultSetUtils {

private static final Logger logger = Logger.getLogger(ResultSetUtils.class.getName());
private static final String COL_SEPARATOR = ";";

public static int getColForLabel(ResultSet rs, String labelname) throws SQLException {
    ResultSetMetaData rsmd = rs.getMetaData();

    for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        if (labelname.equals(rsmd.getColumnLabel(i))) {
            return i;
        }
    }

    throw new SQLException("Invalid label name " + labelname);
}

public static void dump(ResultSet rs) throws SQLException {

    // the order of the rows in a cursor
    // are implementation dependent unless you use the SQL ORDER statement
    ResultSetMetaData meta = rs.getMetaData();
    int colmax = meta.getColumnCount();
    int i;
    Object o;

    StringBuilder sb = new StringBuilder(512);
    for (i = 0; i < colmax; ++i) {
        if(i>0) {
            sb.append(COL_SEPARATOR);
        }
        String s = meta.getColumnName(i + 1);
        sb.append((s == null) ? "NULL" : s);
        s = meta.getColumnTypeName(i + 1);
        sb.append((s == null) ? "(NULL)" : "("+s+")");
    }
    logger.info(sb.toString());


    // the result set is a cursor into the data.  You can only
    // point to one row at a time
    // assume we are pointing to BEFORE the first row
    // rs.next() points to next row and returns true
    // or false if there is no next row, which breaks the loop
    for (; rs.next();) {
        sb = new StringBuilder(512);
        for (i = 0; i < colmax; ++i) {
            if(i>0) {
                sb.append(COL_SEPARATOR);
            }
            o = rs.getObject(i + 1);    // Is SQL the first column is indexed
            sb.append((o == null) ? "NULL" : o.toString());
        }

        logger.info(sb.toString());
    }
}

}

4

2 回答 2

1

访问模式的编程方式是使用 DatabaseMetaData 类:http ://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html

从 getTables() 方法开始,打印出返回的信息。

于 2013-03-06T14:47:36.177 回答
1

pom.xml:

<dependency>
    <groupId>org.apache.derby</groupId>
    <artifactId>derbytools</artifactId>
    <version>10.9.1.0</version>
</dependency>

代码:

new dblook(new String[]{"-d", "jdbc:derby:memory:unit-testing;", "-verbose"});

没有参数来打印帮助:

new dblook(new String[]{});

结果是:

-- Timestamp: 2013-03-09 00:19:49.733
-- Source database is: memory
-- Connection URL is: jdbc:derby:memory:unit-testing;
-- appendLogs: false

-- ----------------------------------------------
-- DDL Statements for schemas
-- ----------------------------------------------

CREATE SCHEMA "ROOT";

-- ----------------------------------------------
-- DDL Statements for tables
-- ----------------------------------------------

CREATE TABLE "ROOT"."BLOG" ("DTYPE" VARCHAR(31) NOT NULL, "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), "BODY" VARCHAR(255), "CREATEDAT" TIMESTAMP, "RAWDATA" BLOB(2147483647), "SUBJECT" VARCHAR(255), "SENDER" VARCHAR(255));

-- ----------------------------------------------
-- DDL Statements for keys
-- ----------------------------------------------

-- primary/unique
ALTER TABLE "ROOT"."BLOG" ADD CONSTRAINT "SQL130309001949220" PRIMARY KEY ("ID");

JDBC 元数据操作似乎缺少一些东西,如索引、触发器等。

于 2013-03-09T00:22:42.957 回答