📝 一句话概括
第十一章走完一条线:认合同(11.1)→ 摸方法(11.2)→ 真跑通(11.3)→ 配池子(11.4)→ 请管家(11.5)——从「会连数据库」到「优雅地连数据库」,JDBC 这座山翻完了。
一、五节串线
| 节 | 主题 | 一句话记忆点 |
|---|---|---|
| 11.1 | 什么是 JDBC | Sun 定的总合同,厂商写实现装 jar,换库只换 jar+url |
| 11.2 | 常用 API | 四大件(调度员/电话线/传话筒/快递箱),ResultSet 光标从表头前出发 |
| 11.3 | JDBC 编程 | 三件准备 + Demo13 CRUD 四连,学会看异常信息是第一基本功 |
| 11.4 | 数据库连接池 | 连接的租车行,池版 close 不是关闭是归还 |
| 11.5 | DbUtils | 现成管家:QueryRunner 管执行,Handler 管形状,一行查全表 |
二、概念速查
- JDBC:Java 官方定的操作数据库接口规范(4.3 接口合同的最大实战)
- 驱动 jar:数据库厂商按合同写的实现类压缩包,导入后 Add as Library 才生效
- 四大件:DriverManager(调度员)→ Connection(电话线)→ Statement(传话筒)→ ResultSet(快递箱)
- url 三段式:
jdbc:mysql://localhost:3306/库名?serverTimezone=... - 两路分工:
executeUpdate增删改返回行数;executeQuery查询返回结果集,串门即炸 - 光标:ResultSet 初始停在表头前,必须先
next();取值列号从 1 起,推荐按列名 - 连接池:预建连接循环借还,
DataSource是 JDK 第二份合同,Druid 是热门实现 - 池版 close:不是关闭,是归还——只借不还池子卡死
- QueryRunner:DbUtils 执行者,
update/query两大方法 - ResultSetHandler:装配工——
BeanHandler一条、BeanListHandler多行、ScalarHandler聚合值 - 装配底层:反射拿列名拼
setXxx(9.1 正式上岗),所以属性名 = 列名是保命规矩 - SQL 注入:拼接 SQL 的安全坑,属于
PreparedStatement的战场(DbUtils 不负责防)
三、代码模板(背这四段)
模板 1:五步骨架(11.2)
Connection conn = DriverManager.getConnection(URL, USER, PWD);
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(sql); // 增删改
ResultSet rs = stmt.executeQuery(sql); // 查询
// while(rs.next()) { rs.getXxx("列名"); }
// 三资源进 try 括号,自动倒序关
模板 2:异常对症(11.3)
ClassNotFoundException → jar 没导入 / 没 Add as Library
Access denied → 账号或密码错
Unknown database → url 里库名写错
模板 3:连接池替换(11.4)
DataSource ds = DruidDataSourceFactory.createDataSource(prop);
Connection conn = ds.getConnection(); // 只换这一行,其余不动
模板 4:DbUtils 查询(11.5)
QueryRunner qr = new QueryRunner(ds);
List<Student> list = qr.query(sql, new BeanListHandler<>(Student.class));
Long count = qr.query("SELECT COUNT(*) FROM student", new ScalarHandler<>());
四、五大名坑回顾
- 光标没挪就取值——
Before start of result set,先next()再说话 - 列号从 0 取——SQL 世界从 1 数数,
rs.getInt(0)直接炸 - update 跑 SELECT——两路串门抛
SQLException,管家也救不了 - 池子只借不还——连接用完忘
close(归还),池子耗尽新请求全体超时 - 属性名 ≠ 列名——DbUtils 装配默默丢列,查出来是
null还不报错
五、收官暗线
本章表面学「怎么连数据库」,暗地里把前面的理论全搬上了生产现场:
- 接口思想(4.3)→ JDBC 合同 + DataSource 合同,换实现不动业务代码
- 多态(4.4)→ 拿到的 Connection 永远是接口类型,运行时看右边
- 反射(9.1)→ 注册驱动
Class.forName+ DbUtils 装配 JavaBean,两处正式上岗 - 工具类思维(10 章起)→ 从自己封装 JDBCUtils 到用现成 DbUtils,重复劳动交给框架
一句话收官:JDBC 是你第一次站在「接口是别人的、实现是别人的、你只管调」的世界门口——这条门后面就是真正的企业级开发(MyBatis、Spring 全在这个思路上加盖)。
六、跨章连线
- 第三章 面向对象(上)/3.3 封装性:JavaBean 的出身,DbUtils 装配的对象全靠它
- 第四章 面向对象(下)/4.3 抽象类和接口:合同思想的源头
- 第四章 面向对象(下)/4.4 多态:接口类型变量运行时看右边的现场
- 5.2 运行时异常与编译时异常:SQLException 的受检判定法
- 第九章 反射机制和注解/9.1 反射概述:Class.forName 与装配引擎两度上岗
- 第十章 I-O/10.2 字节流:-1 哨兵 → 光标 next 的亲戚关系、try-with-resources 姿势
- 第十章 I-O/10.5 序列化和反序列化:同样「给类贴接口当准入证」的思路
七、毕业大题:手写「员工管理小系统」核心层
题目:用 Druid + DbUtils 完成三件事:①按姓名查一个员工并打印;②查全表返回 List<Emp>;③统计总人数。要求说出每步用了什么、为什么。
参考骨架:
DataSource ds = DruidFactory.getDataSource(); // 租车行
QueryRunner qr = new QueryRunner(ds); // 管家
Emp e = qr.query("SELECT * FROM emp WHERE name=?",
new BeanHandler<>(Emp.class), name); // ① 一条 → BeanHandler
List<Emp> all = qr.query("SELECT * FROM emp",
new BeanListHandler<>(Emp.class)); // ② 多行 → BeanListHandler
Long total = qr.query("SELECT COUNT(*) FROM emp",
new ScalarHandler<>()); // ③ 聚合 → ScalarHandler
✅ 自检清单(全打勾才算毕业)
- 能说清 JDBC 合同和驱动 jar 的关系,以及为什么换数据库不用改业务代码
- 四大件各是什么角色,两路方法(update/query)怎么分工
- ResultSet 光标的初始位置和
next()的返回值含义 - 连接池解决什么问题,池版
close的语义变化 - 三大 Handler 各对应什么查询场景
- 能说出「属性名 = 列名」背后的反射原理
下一步学什么
- ☑ 第十二章 多线程 ✅ 已开章——点此复习:进程=工厂、线程=工人、main 主线程身份曝光,11.4「连接不能共用」的账正式挂到本章。
相关笔记
- 第十一章 JDBC/11.1 什么是JDBC:总合同
- 第十一章 JDBC/11.2 JDBC的常用API:四大件的方法地图
- 第十一章 JDBC/11.3 JDBC编程:实战落地与异常对症
- 第十一章 JDBC/11.4 数据库连接池:租车行与 DataSource 第二份合同
- 第十一章 JDBC/11.5 DbUtils:现成管家
- 🏠 主页:返回总入口