在Java中执行SQL时处理所有异常

时间:2012-12-05 14:36:56

标签: java sql

在Java中执行一个SQL语句涉及许多步骤:

  1. 创建连接
  2. 创建声明
  3. 执行语句,创建结果集
  4. 关闭结果集
  5. 关闭声明
  6. 关闭连接
  7. 在每个步骤中都可以抛出SQLException。如果我们要处理所有异常并正确释放所有资源,代码将看起来像4个TRY级别堆叠在一起。

    try {
         Connection connection = dataSource.getConnection();
         try {
               PreparedStatement statement = connection.prepareStatement("SELECT 1 FROM myTable");
               try {
                    ResultSet result = statement.executeQuery();
                    try {
                         if (result.next()) {
                               Integer theOne = result.getInt(1);
                         }
                    }
                    finally {
                         result.close();
                    }
               }
               finally {
                    statement.close();
               }
         }
         finally {
               connection.close();
         }
    }
    catch (SQLException e) {
    // Handle exception
    }
    

    您是否可以提出一种更好(更短)的方式来执行语句,同时仍然释放所有消耗的资源?

6 个答案:

答案 0 :(得分:8)

如果您使用的是Java 7,那么try with resources语句会缩短这一点,并使其更易于维护:

try (Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(queryString); ResultSet rs = ps.execute()) {

} catch (SQLException e) {
    //Log the error somehow
}

请注意,关闭连接会关闭所有关联的StatementsResultSets

答案 1 :(得分:3)

查看Apache Commons DbUtils,特别是closeQuietly()方法。它将正确处理连接/语句/结果集关闭,包括一个或多个为空的情况。

另一种选择是Spring JdbcTemplate,它将大量工作抽象给您,并且您以更多功能方式处理数据库查询。您只需提供一个类作为要为ResultSet的每一行调用的回调。它将处理迭代,异常处理和正确关闭资源。

答案 2 :(得分:0)

我使用我可以调用的静态方法创建一个实用程序类:

package persistence;

// add imports.

public final class DatabaseUtils {

    // similar for the others Connection and Statement
    public static void close(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (Exception e) {
            LOGGER.error("Failed to close ResultSet", e);
        }
    }
}

所以你的代码是:

     Integer theOne = null;
     Connection connection = null;
     PreparedStatement statment = null;
     ResultSet result = null;
     try {
         connection = dataSource.getConnection();
         statement = connection.prepareStatement("SELECT 1 FROM myTable");
         result = statement.executeQuery();
         while (result.next()) {
             theOne = result.getInt(1);
         }
    } catch (SQLException e) {
        // do something
    } finally {
        DatabaseUtils.close(result);
        DatabaseUtils.close(statement);
        DatabaseUtils.close(connection);
    }
    return theOne;

我建议在此方法之外实例化Connection并将其传入。您可以更好地处理事务。

答案 3 :(得分:0)

关闭Connection,即可释放所有资源*。您无需关闭StatementResultSet

*只是确保您没有任何有效交易。

答案 4 :(得分:0)

Connection connection = null;
PreparedStatement statement = null;
ResultSet result = null;
try {
     connection = dataSource.getConnection(); 
     statement = connection.prepareStatement("SELECT 1 FROM myTable");
     result = statement.executeQuery();
     if (result.next()) {
         Integer theOne = result.getInt(1);
     }
}
catch (SQLException e) { /* log error */ }
finally {           
     if (result != null) try { result.close(); } catch (Exception e) {/*log error or ignore*/}
     if (statement != null) try { statement.close(); } catch (Exception e) {/*log error or ignore*/}
     if (connection != null) try { connection.close(); } catch (Exception e) {/*log error or ignore*/}
}

答案 5 :(得分:0)

您的代码可以通过这种方式缩短和编写......

Connection connection = dataSource.getConnection();
PreparedStatement statement = null;
ResultSet result = null;
try {
    statement= connection.prepareStatement("SELECT 1 FROM myTable");
    result = statement.executeQuery();
    if (result.next()) {
        Integer theOne = result.getInt(1);
    }
} catch (SQLException e) {
    // Handle exception

} finally {
    if(result != null) result.close();
    if(statement != null) statement.close();
    if(connection != null) connection.close();
}