清理重复设置和清理Java(JDBC)代码

时间:2009-07-19 22:26:17

标签: java jdbc refactoring

我有太多方法可以重复执行类似

的操作
Statement stmt = null;
ResultSet rstmt = null;
try {
    stmt = conn.createStatement();
    rstmt = stmt.executeQuery(...);
    while (rstmt.next()) {
        //handle rows
    }


} catch (SQLException e) {
    //handle errors

} finally {
    try {rstmt.close();} catch (SQLException ex) {}
    try {stmt.close();} catch (SQLException ex) {}
}

语句和结果集的这种设置/拆卸/清理是重复的,并隐藏了有趣的代码片段。

是否有任何模式或习惯用于处理此问题(不引入任何外部框架)?

5 个答案:

答案 0 :(得分:10)

在Spring Framework中查看SimpleJDBCTemplate。这完全符合你的要求。

如果您不想引入外部框架,那么只需使用它来实现您自己的灵感。

答案 1 :(得分:4)

你想要执行周围的习语。

您可能想问'What is the "Execute Around" idiom?'

(如果你喜欢ASCII图:my weblog on 'Factoring out exception handling'

答案 2 :(得分:4)

您可以创建一个接收SQL查询的方法和一个处理ResultSet的对象。例如:

private void executeSql(String sql, ResultSetHandler handler) {
  Statement stmt = null;
  ResultSet rstmt = null;
  try {
    stmt = conn.createStatement();
    rstmt = stmt.executeQuery(sql);
    while (rstmt.next()) {
      handler.handle(rstmt);
    }
  }
  catch (SQLException e) {
    //handle errors
  }
  finally {
    try {rstmt.close();} catch (SQLException ex) {}
    try {stmt.close();} catch (SQLException ex) {}
  }
}

ResultSetHandler是一个界面:

public interface ResultSetHandler {
  void handle(ResultSet rs) throws SQLException;
}

你可以创建一个实现该接口的匿名类的对象,所以它不会太杂乱。

答案 3 :(得分:1)

您应该重新考虑使用iBatis和Hibernate等Java持久性管理器。这些可以自动化很多样板。我一直在使用iBatis,其中SQL语句都整齐地打包并以XML文件命名,代码量必须是原始JDBC方法的25%左右。您可以逐步重构系统以使用iBatis。

答案 4 :(得分:0)

虽然它没有消除设置和拆卸逻辑,但我更喜欢这种风格使JDBC交互更加愉快:

Statement statement = connection.createStatement();
try {
    ResultSet results = statement.executeQuery(...);
    try {
        while (results.next()) {
            //handle rows
        }
    } finally {
        results.close();
    }
} finally {
    statement.close();
}

通过嵌套try块,您可以自动确保resultsstatement同时调用close()方法,而无需诉诸try / { {1}}块中的{1}}语句。同样,通过在获取对象后立即启动catch块,您无需担心检查finally值(当然,除非try或{{1} })return null - 在这种情况下,你有更大的问题。)