从 hibernate 执行 DDL

发布于 2024-09-08 19:03:21 字数 1655 浏览 10 评论 0原文

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

您发现以下代码有问题吗?我想知道这似乎如此复杂......

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;
}

顺便说一句:对于 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");

I know that SchemaExport should be my friend. But I am using liquibase and want to execute the DDL - pure sql statements - generated from liquibase to recreate the database before every test method.

Do you see problems with the following code? I wonder that this seems to be so complicated ...

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: For liquibase you will need to do:

    // 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");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

—━☆沉默づ 2024-09-15 19:03:21

安全

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

异常处理

完全缺失,例如正确关闭输入流、连接等。此外,如果出现任何SQLExceptions,它也会缺失关于哪些语句失败的详细信息。抛出。 sqlCmd 变量还对失败的语句进行计数,所以我怀疑这个计数器的用处。

解析 SQL/DDL

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

事务处理

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

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

Security

Directly executing unprepared statements may lead to SQL injection. However, you seem to read DDL statements from a static file, so this shouldn't be a problem, just wanted to note that.

Exception Handling

Missing entirely, e.g. properly closing the input streams, the connections etc. Also, it misses having detailed information on which of the statements failed if any of the SQLExceptions are being thrown. sqlCmd variable also counts failed statements, so I doubt the usefulness of this counter.

Parsing SQL/DDL

You're testing for -- style comments, but not for /* */ comments. That'll bite you some day. Also, the parser assumes a SQL statement per line. Longer statements may be multiline and end with semicolons which need to be trimmed. Not sure about how liquibase generates the statements though, so this may not be a real problem.

Transaction Handling

DDL statements cannot be rolled back anyway, so not sure about the transactions being helpful. Please correct me if i'm wrong.

Otherwise, as it's for testing, i looks fine to me too.

美人骨 2024-09-15 19:03:21

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

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

Why don't you simply use the hbm2ddl.auto configuration?

Or use transactional tests that roll the database back to its original state after each and every test?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文