必须显式关闭 ResultSet、Statement 和 Connection,推荐用 try-with-resources 自动管理;若手动关闭,需判空并按 ResultSet→Statement→Connection 顺序在 finally 中独立处理。

Java 中 JDBC 操作数据库后,必须显式关闭 ResultSet、Statement(或 PreparedStatement)和 Connection,否则容易造成连接泄漏、游标耗尽、内存占用上升,尤其在使用连接池时,不关 ResultSet 和 Statement 会导致数据库报“最大打开游标数超限”错误。
优先用 try-with-resources 自动管理(推荐)
JDK 7+ 且 JDBC 驱动支持 JDBC 4.0(如 ojdbc8、mysql-connector-java 5.1+),Connection、Statement、ResultSet 都实现了 AutoCloseable,可直接在 try() 中声明,JVM 会按声明的逆序自动调用 close():
- 资源必须在
try( )括号内完成创建和初始化,不能提前赋值 - 关闭顺序天然是:ResultSet → Statement → Connection,符合依赖逻辑
- 即使执行中抛出异常,所有资源仍会被关闭;若 close 本身也抛异常,会被抑制(suppressed),主异常仍向上抛出
示例:
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT * FROM user WHERE id = ?");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
// 三者已自动关闭,无需手动写 close()手动关闭要严守三要素(兼容旧环境)
若项目受限于 JDK 版本或需精细控制,用 try-catch-finally 也可靠,但必须满足:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 变量提前声明为
null:Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; - 每个
close()独立判空 + 独立 try-catch,避免一个失败中断后续释放 -
finally块中不 return、不 throw,防止掩盖原始异常
关闭顺序不能错:一定是 ResultSet → Statement → Connection
这是由底层依赖决定的:
- ResultSet 内部持有 Statement 引用,Statement 又依赖 Connection
- 如果先 close Connection,再访问 ResultSet 或 Statement,会直接抛 “Connection closed” 或 “Statement closed”
- 即使用了连接池,
conn.close()也只是归还连接,不会自动级联关闭其创建的 Statement 和 ResultSet —— 这不是 JDBC 规范要求,各驱动行为不一致,不可依赖
别指望 GC 回收这些资源
JVM 垃圾回收只管堆内存,不管数据库连接、网络套接字、文件句柄等物理资源。即使方法执行完、局部变量消失,Connection 对应的 TCP 连接、数据库服务端游标、内存缓冲区依然存在,直到被显式关闭或超时回收(不可控、低效、风险高)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










