在Java中执行SQL时处理所有异常
在Java中执行一条SQL语句涉及许多步骤:在Java中执行SQL时处理所有异常,java,sql,Java,Sql,在Java中执行一条SQL语句涉及许多步骤: 创建连接 创建语句 执行语句,创建结果集 关闭结果集 结束语 密切联系 在每个步骤中,都可以抛出SQLException。如果我们希望正确地处理所有异常并释放所有资源,那么代码将如下所示,其中4个级别的TRY堆叠在彼此的顶部 try { Connection connection = dataSource.getConnection(); try { PreparedStatement statement =
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
}
您能提出一种更好(更短)的方法来执行语句,同时释放所有消耗的资源吗?我使用静态方法创建了一个实用程序类,我可以调用:
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;
我建议在这个方法之外实例化连接并将其传入。这样可以更好地处理事务。签出,尤其是签出方法。它将正确处理连接/语句/结果集关闭,包括一个或多个为null的情况
另一种选择是,它将大量工作从您身边抽象出来,您可以以一种功能更强大的方式处理数据库查询。您只需提供一个类作为回调,以便为
结果集的每一行调用该类。它将处理迭代、异常处理和正确关闭资源。如果您使用的是Java 7,该语句将大大缩短此过程,并使其更易于维护:
try (Connection conn = ds.getConnection(); PreparedStatement ps = conn.prepareStatement(queryString); ResultSet rs = ps.execute()) {
} catch (SQLException e) {
//Log the error somehow
}
请注意,关闭连接将关闭所有相关的语句
和结果集
只需关闭连接
,即可释放所有资源*。您不需要关闭语句
和结果集
*只需确保您没有任何活动事务。您的代码可以用这种方式缩短和编写
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*/}
}
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();
}
把整件事都包起来试试看?除非您想知道它具体在哪里失败。如果您将整个块包装到try/catch中并引发异常,您将不知道哪些资源已被占用,需要关闭。@user245106我的评论有点滑稽。如果您使用的是连接池,关闭连接实际上可能不会关闭语句
和结果集
。有趣的是,我不知道这一点。感谢您的提示。JdbcTemplate相当不错,+1此解决方案有一个小问题。connection.close也可能引发SQLException。评论不错。这很好地说明了一个简单的资源管理问题根本不是问题