Java 8+无需Class.forName(),DriverManager自动加载驱动;需确保JAR在classpath、URL格式正确;PreparedStatement防SQL注入且高效;ResultSet遍历必须用if(rs.next());资源按rs→ps→conn逆序关闭,try-with-resources声明顺序影响关闭顺序。

Java中如何正确加载JDBC驱动并建立Connection
Java 8 及以后版本已不再需要显式调用 Class.forName() 加载驱动,DriverManager.getConnection() 会自动触发服务发现机制。但如果你用的是老旧驱动(如 MySQL Connector/J 5.1.x),仍可能遇到 java.sql.SQLException: No suitable driver found 错误。
关键点在于:驱动 JAR 必须在 classpath 中,且 URL 格式必须匹配驱动要求。常见错误是把 mysql-connector-java-8.0.33.jar 放错位置(比如只丢进 IDE 的 lib 目录却没配置为 module dependency)。
- MySQL 8+ 推荐 URL:
jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC - PostgreSQL 示例:
jdbc:postgresql://localhost:5432/mydb - 确保连接参数含
serverTimezone(MySQL)或sslmode(PostgreSQL),否则可能抛出时区/SSL 异常
PreparedStatement比Statement更安全也更高效
直接拼接 SQL 字符串用 Statement 执行,不仅易引发 SQL 注入(比如用户输入 ' OR '1'='1),还会让数据库反复解析相同结构的语句。而 PreparedStatement 预编译后可复用执行计划,并自动转义参数。
注意:占位符 ? 不能用于表名、列名或排序方向(ORDER BY ? 是非法的),这些必须通过白名单校验后字符串拼接。
立即学习“Java免费学习笔记(深入)”;
String sql = "SELECT id, name FROM users WHERE status = ? AND created_at > ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, "active"); ps.setTimestamp(2, Timestamp.from(Instant.now().minusSeconds(86400))); ResultSet rs = ps.executeQuery();
ResultSet遍历时必须检查next()返回值
很多人写 rs.next(); String name = rs.getString("name");,结果空指针——因为 next() 返回 false 时游标不在有效行上,后续取值操作会抛 SQLException。
SHOPEX仿M18紫色版 ,适合综合商城,服饰商城.化妆品商城等使用.程序基于SHOPEX4.8.5 最新版制作. 安装方法:1.解压上传程序至网站根目录.. 访问:域名/bak.(用户名:admin 密码:123456)2.进入帝国备份王后,配置数据库信息.选择-www.taomoban.net目录.还原数据库.3.修改FTP目录下的config/config.php 数据库连接信息.4.登陆
典型场景是查询单条记录(如 SELECT * FROM users WHERE id = ?),应始终用 if (rs.next()) { ... } 而非 while (rs.next())。
-
rs.getString()对 null 值返回null,不是空字符串;需用rs.wasNull()判断是否为数据库 NULL - 不要在循环内重复调用
rs.getMetaData(),它开销较大 - 若只需读取一次结果,记得及时关闭
ResultSet(推荐 try-with-resources)
资源释放顺序和try-with-resources的坑
JDBC 资源(Connection、PreparedStatement、ResultSet)必须按 ResultSet → PreparedStatement → Connection 逆序关闭,否则某些驱动(如 Oracle JDBC)会在关闭 Connection 时强制关闭子资源并吞掉异常。
用 try-with-resources 时要注意:如果多个资源在同一语句中声明,关闭顺序由声明顺序决定(从右到左)。所以应写成:
try (Connection conn = DriverManager.getConnection(url);
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
// 处理结果
} catch (SQLException e) {
// 异常处理
}而不是把 Connection 放最后——那样会导致 ps 和 rs 在 conn 关闭前就被关了,部分驱动会报 “connection closed”。
真正容易被忽略的是:即使用了 try-with-resources,也要在 catch 块里检查 e.getSuppressed(),因为多个资源关闭失败时,只有第一个异常被抛出,其余被压制,不查就永远不知道哪一步挂了。









