Java中JDBC必须按ResultSet→Statement→Connection顺序显式关闭,因存在依赖关系;推荐用try-with-resources自动逆序关闭,资源需在try()内声明,异常时主异常优先、关闭异常被抑制。

Java 中 JDBC 安全关闭数据库连接,核心就两点:关对顺序、关不遗漏。最稳妥的方式是用 try-with-resources,它自动按依赖逆序关闭资源,既简洁又防漏;若需兼容旧环境或手动控制,则必须在 finally 块中严格按顺序逐个关闭,并各自捕获异常。
必须按 ResultSet → Statement → Connection 顺序关闭
这不是约定,而是依赖关系决定的:ResultSet 内部持有 Statement,Statement 又依赖 Connection。先关 Connection,再调 ResultSet.next() 就会直接报 “Connection closed”,且后续 close() 可能跳过,导致资源泄漏。
- ✅ 正确顺序:rs.close() → stmt.close() → conn.close()
- ❌ 错误示例:conn.close() 放在 rs.close() 前 → 查询中途崩溃,rs 和 stmt 实际未释放
- 注意:使用连接池(如 HikariCP)时,conn.close() 是归还连接,不是断开物理连接,但依然必须调用
优先用 try-with-resources(JDK 7+ 推荐)
只要 JDBC 驱动支持 JDBC 4.0(如 ojdbc8、mysql-connector-java 8.x),Connection、Statement、ResultSet 都实现了 AutoCloseable,可放心使用。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 资源必须在
try(...)括号内声明并初始化,例如:try (Connection c = ds.getConnection(); PreparedStatement ps = c.prepareStatement(sql); ResultSet rs = ps.executeQuery()) { ... } - 关闭顺序是声明的逆序:rs 最先关,ps 次之,c 最后关,天然符合依赖逻辑
- 即使 try 块抛异常,close() 仍执行;若 close 过程也出错,会被抑制(suppressed),主异常仍向上抛,可通过
e.getSuppressed()查看
传统 finally 方式要严守三要素
适用于 JDK 6 或需精细控制 close 行为的场景,但容易出错,务必满足以下全部条件:
立即学习“Java免费学习笔记(深入)”;
- 变量提前声明为 null:
Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; - 每个 close() 独立判空 + 独立 try-catch:
避免一个 close 失败(如网络抖动)导致后续资源无法释放 - finally 中不 return、不 throw:
否则可能吞掉 try 或 catch 中的关键异常,掩盖真实问题
别依赖 Connection.close() 自动级联关闭
虽然某些驱动文档提到 conn.close() 会顺带关掉它创建的所有 Statement 和 ResultSet,但这不是 JDBC 规范强制要求,行为因驱动而异,不可靠。
- Oracle、MySQL 官方驱动均不保证该行为
- 显式关闭所有资源才是跨驱动、跨版本的稳定做法
- ORM 框架(如 MyBatis、Hibernate)内部也是按此原则封装的

















