JDBC 体系梳理:驱动、DataSource、连接池(HikariCP/Druid)、ORM 的边界
前言
很多 Java 后端同学天天在 SpringBoot 里配置数据源、使用 MyBatis/JPA,但很容易混淆几个概念:JDBC 驱动、HikariCP、Druid、DataSource。经常会疑惑:Hikari 是驱动吗?能不能随便切换 MySQL 和 PG?Hikari 和 Druid 为什么可以互换?本文把整套 JDBC 体系的分层、职责、边界一次性讲清楚。
一、核心角色先分清
- 数据库服务(MySQL / PostgreSQL) 数据库服务端,是最终存储数据、执行 SQL 的服务,由数据库厂商 / 社区提供。
- JDBC 驱动(mysql-connector、postgresql 驱动包) 驱动实现了 JDK 中的
java.sql.Driver接口,由数据库厂商 / 社区开发。 职责:建立 TCP 连接、和数据库服务端通信、解析数据库私有协议,生成原生 Connection。
驱动和数据库强绑定:连 PG 必须用 PG 驱动,连 MySQL 必须用 MySQL 驱动,不能混用。
- JDBC 规范(JDK 自带接口) JDBC 不是一个框架,是 JDK 提供的一套接口规范,分为两大核心:
java.sql.Driver:驱动接口,给数据库驱动实现;javax.sql.DataSource:数据源接口,现代推荐使用,接口只定义一个方法getConnection(),约定 “如何获取数据库连接”。
⚠️重点:DataSource 接口只负责提供连接,本身不能执行 SQL、不自带连接池。
- 连接池实现:HikariCP / Druid 二者是第三方开发的 Jar 包,实现了 JDK 的
javax.sql.DataSource接口。 在接口基础之上,额外实现连接池能力:连接复用、连接生命周期管理、空闲回收、超时控制、连接泄漏检测。
- HikariCP:SpringBoot2 默认连接池,专精连接管理,轻量、高性能,没有 SQL 解析、监控面板等附加能力;
- Druid:阿里的连接池,除了连接池能力之外,额外自带 SQL 解析器、Filter 链、SQL 审计、防火墙、内置监控页面。
关键点:因为都实现同一个标准 DataSource 接口,所以二者可以无缝替换,上层持久层代码无感知。
- ORM / SQL 映射框架(MyBatis、JPA、JOOQ) 属于上层框架,不直接和驱动、数据库打交道,它只依赖
DataSource接口。 职责:封装 SQL 编写、参数绑定、结果集和 Java 实体映射,简化数据库编码。 它只向 DataSource 索要 Connection,完全不关心底层连接池是 Hikari 还是 Druid。
二、完整调用层级(从上到下)
业务代码 / Controller / Service
↓
MyBatis / JPA / JOOQ(ORM映射层)
↓
DataSource(HikariCP / Druid 连接池)
↓
JDBC标准API:Connection、PreparedStatement、ResultSet
↓
JDBC驱动(mysql/postgresql驱动)
↓
MySQL / PostgreSQL 数据库服务
三、核心时序:连接池获取连接的流程(重点)
- ORM / 业务代码调用
dataSource.getConnection(),向连接池申请连接; - 连接池优先从空闲队列取出可用连接,并校验连接有效性;
- 有空闲可用:包装成代理 Connection直接返回;
- 无空闲、未达到最大连接数:调用底层 JDBC 驱动,创建原生 TCP 连接,存入池,包装代理返回;
- 无空闲、池已满:线程排队等待,超时抛出异常;
- 上层拿到代理 Connection,创建 PreparedStatement 执行 SQL;
- 使用完毕,调用
connection.close();
✅ 这里是连接池最核心的魔法:代理 Connection 拦截 close 方法,不会关闭 TCP 连接,而是把连接归还到空闲队列; ✅ 只有连接过期(max-lifetime)、服务关闭销毁连接池的时候,才会调用原生 Connection.close (),真正断开 TCP。
四、HikariCP 和 Druid 切换,哪些要改、哪些不动
✅ 完全不用改动:
- 业务代码、Mapper、SQL、实体类;
- url、username、password、driver-class-name(数据库连接信息);
- MyBatis/JPA 配置。
⚠️ 需要改动:
- Maven 依赖:引入对应 starter(druid-spring-boot-starter / 使用默认 Hikari 无需额外引入);
- YAML 配置前缀与参数名:
- Hikari:
spring.datasource.hikari.maximum-pool-size - Druid:
spring.datasource.druid.max-active
- Hikari:
两套连接池参数命名不一样,不要直接复制混用。
五、两个经典误区澄清
- ❌ 误区:Hikari/Druid 是 JDBC 驱动 ✅ 纠正:驱动是和数据库通信的;Hikari/Druid 是 DataSource 的实现,包装驱动,负责连接管理。
- ❌ 误区:DataSource 接口用来执行 SQL ✅ 纠正:DataSource 只负责
getConnection();执行 SQL、查询数据靠拿到的 Connection、PreparedStatement。
六、选型小结
- 优先 HikariCP:高并发核心链路、已有 APM(SkyWalking/Pinpoint)做 SQL 监控,追求低延迟、稳定;
- 选择 Druid:需要开箱即用 SQL 审计、慢 SQL 统计、SQL 防火墙、内置监控页面;
注意:Druid 的 SQL 防火墙、SQL 解析不属于 JDBC 规范,是 Druid 额外增强能力,PG 空间函数(PostGIS)容易被 WallFilter 误拦截。
七、一句话速记
MySQL、PostgreSQL 是数据库服务;
驱动实现 JDK 的java.sql.Driver,负责 TCP 通信;
JDK 提供javax.sql.DataSource标准接口,约定获取连接;
HikariCP、Druid 是第三方 DataSource 实现,实现连接池复用能力;
MyBatis/JPA 等 ORM 框架依赖 DataSource,底层连接池可插拔替换。
浙公网安备 33010602011771号