从hibernate执行DDL

时间:2010-07-10 21:09:37

标签: sql hibernate ddl

我知道SchemaExport应该是我的朋友。但我正在使用liquibase并且想要执行DDL - 纯sql语句 - 从liquibase生成以在每个测试方法之前重新创建数据库。

您是否看到以下代码存在问题?我想知道这似乎太复杂了......

public static int executeScript(String sqlFileOnClasspath) {
    Session sess = getSessionFactory().openSession();
    Transaction ta = sess.beginTransaction();
    int sqlCmd = 0;

    try {
        BufferedReader bReader = new BufferedReader(new InputStreamReader(
                  Util.class.getResourceAsStream(sqlFileOnClasspath), "UTF-8"));
        String line;
        while ((line = bReader.readLine()) != null) {
            if (line.startsWith("--") || line.trim().isEmpty())
                continue;

            final String tmp = line;
            sess.doWork(new Work() {

                @Override
                public void execute(Connection connection) throws SQLException {
                    connection.createStatement().execute(tmp);
                }
            });
            sqlCmd++;
        }
    } catch (Exception ex) {
        log.error("Couldn't execute " + sqlFileOnClasspath, ex);
    } finally {
        ta.commit();
        sess.close();
    }

    return sqlCmd;
}

BTW:对于liquibase,你需要做:

    // remove all hibernate managed tables
    SchemaExport schemaTool = new SchemaExport(getConfiguration()); 
    schemaTool.drop(false, true);

    // DROP TABLE DATABASECHANGELOGLOCK;
    // DROP TABLE DATABASECHANGELOG;
    executeScript("/drop-none-hib.sql");

    // now execute the DDL statements from liquibase
    int sqlCmd = executeScript("/schema.sql");
    log.info("Executed " + sqlCmd + " sql commands");

2 个答案:

答案 0 :(得分:1)

安全

直接执行未准备好的语句可能会导致SQL注入。但是,您似乎从静态文件中读取DDL语句,因此这不应该是一个问题,只是要注意这一点。

异常处理

完全缺席,例如正确关闭输入流,连接等。此外,如果抛出SQLExceptions中的任何一个,它错过了有关哪些语句失败的详细信息。 sqlCmd变量也计算失败的语句,所以我怀疑这个计数器是否有用。

解析SQL / DDL

您正在测试--样式评论,但不会测试/* */评论。有一天你会咬你的。此外,解析器假定每行一条SQL语句。较长的语句可能是多行的,并以分号结束,需要进行修剪。不确定liquibase如何生成语句,所以这可能不是一个真正的问题。

交易处理

无论如何都无法回滚DDL语句,因此不确定有用的事务。如果我错了,请纠正我。

否则,因为它是用于测试,我看起来也很好。

答案 1 :(得分:0)

为什么不简单地使用hbm2ddl.auto配置?

或者使用事务测试在每次测试后将数据库回滚到其原始状态?