java 7 引入的 try-with-resources 语法会自动调用实现 autocloseable 接口的资源对象的 close() 方法,因此在使用 jdbc connection 时,只需在 try 括号中声明并初始化连接对象即可。具体做法是将 drivermanager.getconnection() 的返回值直接赋值给局部变量,并在 catch 块中处理可能抛出的 sqlexception。这样做可以确保无论代码块正常结束还是发生异常,连接都会被自动关闭,从而避免数据库连接泄漏。

如何正确捕获和处理 SQL 异常?
在 try-with-resources 结构中,必须使用 catch (SQLException e) 来捕获数据库操作中的异常。由于 getConnection、创建 Statement 以及执行查询都会抛出该异常,因此需要在同一个 catch 块中统一处理。如果希望保留由 close() 引发的异常(例如连接关闭失败),可以使用 Java 9 提供的 addSuppressed() 机制或直接在 finally 块外通过多 catch 子句区分,但通常业务逻辑中只需关注主要执行的 SQL 错误。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "password";
// 在 try 括号中初始化连接,自动管理生命周期
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE IF NOT EXISTS users (id INT)");
System.out.println("Table created successfully.");
} catch (SQLException e) {
// 捕获所有 JDBC 相关异常
System.err.println("Database error: " + e.getMessage());
e.printStackTrace();
}
}
}
运行上述代码后,控制台将输出 "Table created successfully."。如果数据库服务未启动或凭据错误,则会在 catch 块中打印具体的错误信息,且连接不会因程序退出而残留。
立即学习“Java免费学习笔记(深入)”;
Statement 是否也需要在 try-with-resources 中声明?
是的,Statement、PreparedStatement 和 ResultSet 同样实现了 AutoCloseable 接口,因此也应当在 try-with-resources 语句中声明。可以在同一个 try 括号内用分号分隔多个资源,或者嵌套使用多个 try 块。推荐的做法是在同一行或连续几行中声明 Connection 和 Statement,这样当外层作用域结束时,它们会按照声明的逆序自动关闭:先关闭 Statement,再关闭 Connection。这种顺序关闭符合 JDBC 规范,能确保资源释放的彻底性。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MultiResourceExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "password";
// 同时声明 Connection 和 Statement
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1")) {
if (rs.next()) {
System.out.println("Query executed: " + rs.getInt(1));
}
} catch (SQLException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
执行该程序后,输出结果为 "Query executed: 1"。在此过程中,ResultSet 首先被自动关闭,接着是 Statement,最后是 Connection。这种链式关闭机制确保了即使在执行查询时发生异常,之前打开的资源也不会被遗漏。


















