在Java中执行一个SQL语句涉及许多步骤:
在每个步骤中都可以抛出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
}
您是否可以提出一种更好(更短)的方式来执行语句,同时仍然释放所有消耗的资源?
答案 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
}
请注意,关闭连接会关闭所有关联的Statements
和ResultSets
。
答案 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
,即可释放所有资源*。您无需关闭Statement
和ResultSet
。
*只是确保您没有任何有效交易。
答案 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();
}