2010-07-10 56 views
0

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

您是否看到以下代码存在问题?我不知道,这似乎是那么复杂......

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

回答

1

安全

直接执行措手不及声明可能导致SQL注入。然而,你似乎从静态文件中读取DDL语句,所以这不应该是一个问题,只是想说明一点。

异常处理

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

解析SQL/DDL

您将测试--风格的注释,但不为/* */意见。那会让你有一天感到痛苦。此外,解析器每行假定一条SQL语句。较长的语句可能是多行的,并以需要修剪的分号结尾。不知道liquibase如何生成语句,因此这可能不是一个真正的问题。

事务处理

DDL语句无法反正回滚,所以不知道该交易是有帮助的。如果我错了,请纠正我。

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

+0

很酷,非常感谢!对于TA处理:我希望你知道它;-) – Karussell 2010-07-10 21:31:22

+1

当一个DDL执行成功时,一个COMMIT被隐式执行,所以你不能手动回滚。但是,如果DDL错误,它会自动回滚(例如,DROP TABLE将执行成功并且该表永远消失,或者它不会工作,表存在且处于一致状态)http://searchoracle.techtarget。 com/answer/Do-DDL-statements-roll-back-and-why – mhaller 2010-07-10 21:37:45

+0

再次感谢! (目前链接不工作:-() – Karussell 2010-07-11 21:45:48

0

你为什么不干脆用hbm2ddl.auto配置?

还是使用事务测试,在每次测试之后将数据库回滚到其原始状态?

+0

在引擎盖下使用SchemaExport我认为=>正如我所说:liquibase创建+为我管理DDL。 – Karussell 2010-07-10 21:14:53

+0

是的,我想过“交易测试”,但我经常在我的测试中提交一些东西,例如测试是否会抛出一些异常(独特约束或乐观锁等) – Karussell 2010-07-10 21:18:17