1

単体テストで Hibernate Entitymanager 4.1.9.Final で Apache Derby 10.9.x を使用しています。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);
    }

public class 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

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 に答える
1

スキーマにプログラムでアクセスする方法は、DatabaseMetaData クラスを使用することです: http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html

getTables() メソッドから始めて、返された情報を出力します。

于 2013-03-06T14:47:36.177 に答える