JDBC连接需正确配置URL、避免硬编码凭据、用try-with-resources管理资源;必须用PreparedStatement防SQL注入;ResultSet操作要先调next();事务需手动commit/rollback并恢复auto-commit。

怎么用 DriverManager.getConnection() 建立 JDBC 连接
核心是拿到一个 Connection 对象,但不能只写个 URL 就完事。常见错误是忽略驱动加载(JDBC 4.2+ 可省略)和异常处理不完整,导致程序崩溃却看不出哪错了。
- URL 格式必须严格:例如 MySQL 是
jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC,漏掉useSSL或时区参数在新版本会报SQLException: The server time zone value 'XXX' is unrecognized - 用户名密码不能硬编码,尤其别写在
main方法里;建议从系统属性、环境变量或配置文件读取 - 务必用
try-with-resources包裹Connection、Statement、ResultSet,否则连接不关闭会快速耗尽数据库连接池
为什么 PreparedStatement 比 Statement 更安全且快
不是“推荐用”,而是只要带用户输入就必须用 PreparedStatement。用 Statement 拼 SQL 字符串等于主动给 SQL 注入开后门,而且每次执行都要重新编译 SQL,性能差。
-
Statement示例(危险):stmt.execute("SELECT * FROM user WHERE name = '" + inputName + "'")—— 输入' OR '1'='1就全表泄露 -
PreparedStatement正确写法:ps = conn.prepareStatement("SELECT * FROM user WHERE name = ?"); ps.setString(1, inputName); - 预编译对批量操作更明显:用
addBatch()+executeBatch()比循环执行单条快数倍
查数据时怎么避免 ResultSet.next() 调用错位
这是新手最常踩的坑:忘了调用 next() 就直接 getString(),结果抛 SQLException: Before start of result set;或者循环里多调一次 next(),跳过第一行。
- 查询单行:必须先
if (rs.next()) { ... },不能直接进while - 查询多行:只能用
while (rs.next()) { ... },里面再取字段;不要在循环条件里再写rs.next() - 字段取值别依赖列名拼写大小写 —— MySQL 默认不区分,但 PostgreSQL 和 Oracle 区分;优先用列序号,如
rs.getString(1)
事务控制中 conn.setAutoCommit(false) 后必须手动 commit() 或 rollback()
设了手动提交却不显式调用 commit(),连接一关事务就回滚,你以为成功了其实什么都没存;更糟的是没写 catch 里的 rollback(),异常后锁一直挂着。
立即学习“Java免费学习笔记(深入)”;
- 标准写法:用
try执行业务逻辑,catch中conn.rollback(),finally中conn.setAutoCommit(true)(恢复默认) - 别在事务里混用不同连接对象 —— 一个
Connection开的事务,不能用另一个Connection提交 - 长事务(比如导出百万行)容易锁表,要考虑拆成小批次,每批单独 commit
JDBC 看似简单,但每个接口背后都有状态机逻辑,Connection 的 auto-commit 模式、ResultSet 的游标位置、PreparedStatement 的参数绑定时机,稍不注意就掉进静默失败的坑里。










