位置
服务器地址、端口和数据库名
把数据库访问接入可维护的应用结构
JDBC 接口、结果集处理和 MVC 分层可以组织成可检查的应用流程
Statement、PreparedStatement 或 CallableStatementResultSet 的最小遍历与类型读取结构应用程序通过 JDBC API 访问数据,不直接接触数据库文件或厂商内部函数

不等于完全可移植。URL、驱动、SQL 方言、类型映射、权限和模式仍可能需要适配
应用只需提供目标数据源所需的连接参数
服务器地址、端口和数据库名
用户名、密码和权限
目标 DBMS 和匹配驱动
01
02DriverManager.getConnection(URL, user, password) → Connection
DataSource.getConnection() → ConnectionDataSource 可以由应用服务器或连接池统一配置;应用代码不应把凭据散落在业务方法中
不同对象承担不同生命周期责任
| API | 主要职责 | 常见调用 |
|---|---|---|
DriverManager/DataSource | 取得连接 | getConnection(...) |
Connection | 管理连接和事务边界 | prepareStatement()、prepareCall()、close() |
Statement | 执行静态 SQL,不负责参数绑定 | 固定语句 |
PreparedStatement | 执行参数化 SQL | ?、setXXX() |
CallableStatement | 调用存储过程 | 输入输出参数 |
ResultSet | 读取查询结果 | next()、getXXX() |
getConnection() 属于 DriverManager 或 DataSource;Connection 负责在连接建立后创建语句、管理事务和释放连接
先判断 SQL 的结果形态,再选择对应的 execute 方法
| 方法 | 适用场景 | 应用拿到的结果 |
|---|---|---|
executeQuery() | SELECT 等查询 | 一个 ResultSet |
executeUpdate() | INSERT、UPDATE、DELETE,以及部分 DDL | 受影响的行数或产品定义的更新结果 |
execute() | 可能产生多种结果的语句或过程调用 | 再取 ResultSet、更新行数或过程输出 |
01
02
03
04
05CallableStatement cs = conn.prepareCall("{CALL compGPA(?,?)}");
cs.setString(1, sno);
cs.registerOutParameter(2, Types.REAL);
cs.execute();
float gpa = cs.getFloat(2);CallableStatement 通过 JDBC 调用存储过程;具体占位符、类型和结果处理按目标 DBMS 与驱动核对
每一步都有输入、输出和失败时的处理边界
DataSource,获取 ConnectionResultSet、更新行数或过程输出,并执行业务逻辑ResultSet → Statement → Connection 逆序关闭或归还JDBC 4 以后驱动可能由服务机制自动发现;任一步异常都要进入资源释放路径,try-with-resources 可覆盖成功和异常路径
输入值进入 SQL,查询结果再回到 Java 变量
?→setXXX()→SQL 参数 输出:ResultSet→next()→getXXX()→Java 变量| 方向 | 负责什么 | 边界 |
|---|---|---|
| 参数绑定 | 把 Java 值按类型传给 ? | 不拼接 SQL 结构 |
| 类型映射 | 在 SQL 类型与 Java 类型间转换 | 选择匹配的 setXXX/getXXX |
| 结果读取 | 移动游标并读取当前行 | 先 next(),再 getXXX() |
参数化可降低 SQL 注入风险,但不替代权限、业务校验和事务控制
该代码展示参数绑定、遍历和类型读取的边界;完整 Web 项目还需要控制器、模型和视图
01
02
03
04
05
06
07
08
09
10
11
12String sql =
"SELECT Sno, CAtype FROM ClassAssess WHERE Tno = ?";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, tno);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String rowSno = rs.getString("Sno");
boolean type = rs.getBoolean("CAtype");
}
}
}setXXX 是应用到 SQL 的输入绑定;next() == true 才有有效行;getXXX 是结果到 Java 的读取映射
默认结果集游标从第一行之前开始,并按行向前移动;next() 返回布尔值
getXXX(列名/从 1 开始的列号)→应用处理只有移动到有效行后才能读取列;ResultSet 游标由 JDBC 结果对象管理,过程化 SQL 游标由数据库程序定义和使用
频繁建连或忘记关闭都会拖累性能;try-with-resources 可覆盖异常路径
| 资源 | 关闭顺序 | 目的 |
|---|---|---|
ResultSet | 第一层 | 释放结果集资源 |
| 语句对象 | 第二层 | 释放执行资源 |
Connection | 最后一层 | 关闭或归还连接 |
连接池中的 Connection | close() 后交回池 | 避免反复建立物理连接 |
不能。资源通常按获取顺序的反向释放;池耗尽、连接泄漏和归还失败都需要监控
Controller 接收请求,Model 执行业务,View 呈现结果
同一 Model 可以服务网页、接口或其他呈现方式
教师回复一条课程评价时,Controller、Model、DAO 和 View 各自承担不同职责
Tno + TCno + Sno + FeedbackreplyFeedback,交给 DAO/JDBC 更新 ClassAssessDAO 和 ORM 降低重复和耦合,但不替代数据库判断
把 SQL/JDBC 访问封装成查询或更新方法
映射关系、列与业务对象,减少手写常规 CRUD SQL
或 Model→持久层/DAO→ORM→DBMS`事务、权限、查询性能和数据语义仍需要开发者负责
在频繁或并发访问时可能减少连接建立开销;应用结束使用后把连接归还给池
| 方式 | 请求行为 | 性能影响 |
|---|---|---|
| 每次新建 | 建立、使用、关闭 | 连接开销反复发生 |
| 连接池 | 借用、使用、归还 | 复用物理连接 |
| 池治理 | 上限、超时、健康检查、回收 | 泄漏或耗尽需要监控 |
可靠的数据库应用同时需要接口规范和结构解耦
使用驱动/数据源、参数绑定、类型映射和资源释放
CallableStatement、ResultSet.next/getXXX
用 MVC、DAO/ORM 和连接池组织分层,并区分实验与迁移任务
实验 8.4 练 JDBC 连接与数据操纵;习题 8.4 讨论异构迁移;实验 8.5 承担综合应用
compGPA 各选哪种 JDBC API??、setXXX、next()、getXXX 分别负责什么方向?ResultSet、语句或连接会有什么风险?资源应按什么顺序释放?execute() 后如何判断并取得 ResultSet、更新行数或过程输出?Tno、TCno、Sno、Feedback 经过 Controller、Model、DAO/JDBC 和 View?