《Java 100 天进阶之路》第88篇:JDBC与连接池(2026版)
第88篇JDBC与连接池2026版系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第87篇MyBatis源码阅读 |➡️ 下一篇第89篇MySQL面试压轴题一、核心知识点JDBC 体系架构API 层 → 驱动层厂商实现→ SPI 层Driver动态加载三种 StatementStatement静态SQL、PreparedStatement预编译防注入、CallableStatement存储过程PreparedStatement防注入原理SQL 模板预编译 → 参数独立传递 → 只作为数据处理连接池核心概念DataSource替代DriverManagerHikariCPvsDruid选型连接池核心参数maximum-pool-size、connection-timeout、max-lifetime、idle-timeout2026架构演进R2DBC响应式虚拟线程 传统JDBC简单替代方案动态治理配置中心联动Nacos/Apollo、弹性伸缩、连接泄漏熔断可观测性OpenTelemetry Micrometer 统一指标采集安全加固SQL 防火墙WallFilter、字段级加密jasypt、数据库代理层现代化语法JDK 21RecordJdbcTemplatetry-with-resources二、通俗讲解1分钟开心学1. JDBC 是什么JDBC 是 Java 操作数据库的官方标准 API。它定义了Connection、Statement、ResultSet等接口由各数据库厂商提供具体实现如 MySQL Connector/J。生活类比JDBC 就像手机充电器的统一接口标准USB-C。你只需按标准插拔不用管充电头内部怎么变压——标准由 Java 制定各数据库厂商提供“充电头”驱动。2. 连接池是什么每次操作数据库都创建和关闭连接是非常昂贵的操作TCP 三次握手 认证。连接池在程序启动时预先创建一批连接使用时“借”用完“还”省去反复创建销毁的开销。生活类比没有连接池每次用水都要现挖一口井。有连接池提前建好水库用水时直接开闸取水。3. 为什么 PreparedStatement 能防 SQL 注入普通Statement是字符串拼接用户输入 OR 11会被拼进 SQL变成恒真条件绕过登录。PreparedStatement先将 SQL 模板发送给数据库预编译参数值通过占位符独立传递只作为数据处理不被解析为 SQL 逻辑从根本上杜绝注入。一句话总结Statement把用户输入当“代码”拼进去PreparedStatement把用户输入当“数据”传进去。4. 2026架构新视角响应式 vs 虚拟线程传统 JDBC 连接池阻塞 I/O通过大连接池应对并发。最简单、最成熟适合 90% 的业务系统。R2DBC响应式非阻塞 I/O一个连接可多路复用处理多个请求。适合网关、实时数据流、超高并发场景。虚拟线程 传统 JDBCJDK 21 引入虚拟线程用轻量级线程替代平台线程。使用传统 JDBC 也能获得接近响应式的并发能力且代码无需改造是 2026 年主流推荐方案。一句话选型先尝试虚拟线程 传统 JDBC不够再上 R2DBC。5. HikariCP vs Druid vs R2DBC 一句话定位选型定位适用场景HikariCP极速、轻量高并发互联网应用Spring Boot 默认Druid监控型全功能需要深度 SQL 分析、审计的中大型企业R2DBC响应式非阻塞网关、实时流处理、超高并发 I/O 密集型三、实操代码案例 场景说明3.1 JDBC 基础操作try-with-resourcespublicUsergetUserById(intuserId){StringsqlSELECT id, name, age FROM user WHERE id ?;try(ConnectionconnDriverManager.getConnection(url,username,password);PreparedStatementpstmtconn.prepareStatement(sql)){pstmt.setInt(1,userId);try(ResultSetrspstmt.executeQuery()){if(rs.next()){returnnewUser(rs.getInt(id),rs.getString(name),rs.getInt(age));}}}catch(SQLExceptione){log.error(查询失败,e);}returnnull;}关键点ResultSet也需要在嵌套的 try-with-resources 中关闭生产环境用DataSource替代DriverManager。3.2 SQL 注入演示 vs PreparedStatement 防护❌ 危险写法StringsqlSELECT * FROM users WHERE username username AND password password;Statementstmtconn.createStatement();ResultSetrsstmt.executeQuery(sql);// 攻击者输入 username admin --直接绕过密码校验✅ 安全写法StringsqlSELECT * FROM users WHERE username ? AND password ?;try(PreparedStatementpstmtconn.prepareStatement(sql)){pstmt.setString(1,username);pstmt.setString(2,password);ResultSetrspstmt.executeQuery();// 参数作为纯数据传递}3.3 批量操作优化publicint[]batchInsertOrders(ListOrderorders){StringsqlINSERT INTO orders (user_id, amount, status) VALUES (?, ?, ?);try(ConnectionconndataSource.getConnection();PreparedStatementpstmtconn.prepareStatement(sql)){for(Orderorder:orders){pstmt.setInt(1,order.userId());pstmt.setBigDecimal(2,order.amount());pstmt.setInt(3,order.status());pstmt.addBatch();}returnpstmt.executeBatch();}}3.4 Spring Boot HikariCP 配置⚠️重要生产环境禁止硬编码用户名和密码。以下使用环境变量占位符密码需通过 Kubernetes Secret 或配置中心注入。spring:datasource:url:jdbc:mysql://localhost:3306/testdb?useUnicodetrueserverTimezoneAsia/Shanghaiusername:${DB_USERNAME:app_user}# 使用环境变量禁止硬编码password:${DB_PASSWORD:changeme_in_production}# 使用环境变量禁止硬编码driver-class-name:com.mysql.cj.jdbc.Driverhikari:minimum-idle:10maximum-pool-size:20connection-timeout:5000idle-timeout:60000max-lifetime:300000connection-test-query:SELECT 1leak-detection-threshold:5000# 开发/测试环境开启通过环境变量注入凭证# 方式一直接注入本地开发exportDB_USERNAMEmyappexportDB_PASSWORDMyStrongPssw0rdjava-jarmyapp.jar# 方式二Docker 容器注入dockerrun-eDB_USERNAMEmyapp-eDB_PASSWORDMyStrongPssw0rd myapp:latest# 方式三Kubernetes Secret生产推荐# 1. 创建 Secretkubectl create secret generic db-credentials --from-literalusernamemyapp --from-literalpasswordMyStrongPssw0rd# 2. 在 Deployment 中引用密码自动注入 Pod 环境变量3.5 Druid 配置与监控spring:datasource:type:com.alibaba.druid.pool.DruidDataSourcedruid:username:${DB_USERNAME:app_user}password:${DB_PASSWORD:changeme_in_production}initial-size:5max-active:20max-wait:60000stat-view-servlet:enabled:trueurl-pattern:/druid/*login-username:${DRUID_ADMIN_USER:admin}# 生产用强密码 环境变量login-password:${DRUID_ADMIN_PASS:admin}# 生产用强密码 环境变量filter:stat:log-slow-sql:trueslow-sql-millis:2000merge-sql:true# 必须开启否则SQL统计失真wall:config:delete-whitelist:false# 禁止无where条件的delete生产经验merge-sql: true能将SELECT * FROM user WHERE id 1和id 2合并统计否则监控数据失真。强烈建议为 Druid 监控页配置独立的强密码不低于 16 位含大小写字母、数字、特殊符号并通过环境变量注入。3.6 JDK 21 Record JdbcTemplate// 定义不可变数据载体publicrecordUser(Longid,Stringname,Integerage){}// JdbcTemplate 查询RepositorypublicclassUserDao{privatefinalJdbcTemplatejdbcTemplate;publicListUserfindAll(){StringsqlSELECT id, name, age FROM user;returnjdbcTemplate.query(sql,(rs,rowNum)-newUser(rs.getLong(id),rs.getString(name),rs.getInt(age)));}}3.7 动态治理Apollo 动态刷新 HikariCP生产环境使用配置中心动态调整连接池避免重启ComponentRefreshScopepublicclassDynamicDataSourceConfig{Value(${db.pool.max-size:20})privateintmaxPoolSize;BeanRefreshScopepublicHikariConfighikariConfig(){HikariConfigconfignewHikariConfig();config.setMaximumPoolSize(maxPoolSize);// 其他配置...returnconfig;}}原理Nacos/Apollo 配置变更时RefreshScope触发 Bean 重新创建新连接立即生效。3.8 R2DBC 响应式示例适用场景网关、实时流处理、超高并发 I/O 密集型RepositorypublicclassReactiveUserDao{privatefinalDatabaseClientclient;publicFluxUserfindAll(){returnclient.sql(SELECT id, name, age FROM user).map((row,meta)-newUser(row.get(id,Long.class),row.get(name,String.class),row.get(age,Integer.class))).all();}}四、避坑要点问题错误/误区后果正确做法SQL 注入使用Statement拼接用户输入数据泄露、删库使用PreparedStatement参数化查询连接泄漏未关闭Connection/Statement/ResultSet连接耗尽服务不可用try-with-resources自动关闭线程安全多线程共享Connection数据错乱每个线程从连接池获取独立连接max-lifetime过大超过 MySQLwait_timeout连接被 MySQL 断开池中不知设为 5~30 分钟小于 MySQLwait_timeoutmaximum-pool-size过大数据库连接数耗尽数据库拒绝连接根据压测调整一般 10~30Druidmerge-sql未开启同 SQL 不同参数被分别统计SQL 监控数据失真merge-sql: trueDriverManager vs DataSource使用DriverManager.getConnection()无法利用连接池使用DataSource 连接池监控盲区未配置监控指标生产问题无法定位配置 Druid 或接入 OpenTelemetry连接池过度追求“动态调整”频繁动态修改连接池大小触发连接重创性能抖动配置中心联动时设置合理的变更阈值如变化超过20%才触发避免频繁调整五、面试高频考点Q1Statement、PreparedStatement、CallableStatement的区别Statement执行静态 SQL有注入风险PreparedStatement支持预编译和参数化查询防注入且可复用执行计划CallableStatement用于调用存储过程。Q2PreparedStatement为什么能防止 SQL 注入SQL 模板先发送给数据库预编译参数值通过占位符独立传递仅作为数据处理不被解析为 SQL 逻辑从根本上杜绝注入。Q3HikariCP 和 Druid 如何选型HikariCP极致性能、轻量级适合高并发场景Druid功能全面内置 Web 监控、SQL 防火墙、慢查询分析适合需要深度监控的中大型企业。Q4连接池的核心参数有哪些maximum-pool-size最大连接数、connection-timeout获取连接超时、max-lifetime连接最大存活时间必须小于 MySQLwait_timeout、idle-timeout空闲连接回收时间。Q5DriverManager和DataSource的区别DriverManager每次创建新连接无法利用连接池DataSource是 JDBC 2.0 引入的标准接口支持连接池、分布式事务等生产环境推荐使用。Q6 R2DBC 和 JDBC 连接池的设计理念有何不同JDBC 连接池基于“线程安全”和“复用昂贵连接”一个连接同时只能被一个线程使用而 R2DBC 连接池基于“非阻塞”和“多路复用”一个连接可以处理多个并发请求适合 I/O 密集型场景。Q7 2026 年推荐用 R2DBC 还是虚拟线程 传统 JDBC优先推荐虚拟线程 传统 JDBC代码无需改造JDK 21 原生支持已能满足绝大多数场景。如果业务是网关或超高并发 I/O 密集型再考虑 R2DBC。Q8 如何实现数据库连接的平滑下线无损上线结合 HikariCP 的配置和数据库代理如 Pgbouncer。在应用重启时先将连接池中的连接标记为“不可用”等待当前事务提交后再断开连接避免connection reset异常。也可以通过配置中心动态调小maximum-pool-size让连接自然回收。Q9 如何防止应用把数据库连接打满三层防护① 应用层设置合理的maximum-pool-size② 数据库层设置max_connections并配置用户级限制③ 中间件层如 Sentinel对数据库 RT 进行熔断降级。六、练习题代码题使用PreparedStatement实现用户登录校验要求防 SQL 注入并对比Statement字符串拼接的漏洞。 思路分别用Statement和PreparedStatement实现登录输入admin --测试观察Statement如何被绕过。配置题基于 Spring Boot 配置 HikariCP要求最大连接数 30、连接超时 3 秒、连接最大存活 10 分钟并开启泄漏检测。 思路配置maximum-pool-size: 30、connection-timeout: 3000、max-lifetime: 600000、leak-detection-threshold: 5000。分析题某生产系统频繁出现Connection is not available错误连接池配置maximum-pool-size10并发请求 50。如何排查 思路① 检查是否有连接泄漏未正常关闭② 增大maximum-pool-size并压测③ 检查数据库max_connections是否足够④ 检查慢 SQL 是否占用连接过长⑤ 开启leak-detection-threshold定位泄漏代码。 你的学习进度当前第88篇 / 共108篇 ·进阶篇数据库与持久层框架第83~90篇✅ 已完成基础篇44篇 第91~ 96篇Redis/MQ 第83~88篇 正在学第88篇⏳ 待学习第89~ 90篇 第97~108篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 本专栏每篇都包含避坑表 面试高频考点 练习题。每天30分钟100天拿offer 下一篇文章预告《第89篇MySQL面试压轴题2026版》内容简介汇总 30 道 MySQL 大厂面试真题索引优化、事务隔离级别、MVCC、锁机制、SQL 调优、分库分表、读写分离等附标准话术 加分回答 实战经验助你轻松应对 MySQL 面试。 学完这篇你将能应对 90% 的 MySQL 面试题从“会用”到“精通”。福利提醒评论区留言“JDBC”可领取《JDBC 与连接池核心参数速查表》PDF。《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送

相关新闻

ASM485S 半双工 RS485 收发器高可靠性与环境适应性及应用解析

ASM485S 半双工 RS485 收发器高可靠性与环境适应性及应用解析

引言RS485 总线凭借传输距离远、抗干扰能力强、支持多节点组网、布线便捷等优势,成为工业控制、远距离数据传输、设备联网的主流通信总线。在商业航天、工业现场总线、特种远程监控等高可靠场景中,RS485 收发器不仅需要满足基础通信性能,更要…

2026/6/18 15:46:07阅读更多 →
Edge AI工程师晨间作战地图:每日硬核技术动态与实操指南

Edge AI工程师晨间作战地图:每日硬核技术动态与实操指南

1. 项目概述:这不是一份新闻简报,而是一份Edge AI工程师的晨间作战地图 “Edge AI Daily 早报(4月15日)”——看到这个标题,别急着划走,也别把它当成又一份泛泛而谈的行业资讯合集。在我过去十年跑遍深圳硬…

2026/6/18 15:46:07阅读更多 →
CNN与迁移学习:从像素到预测的视觉智能工作流

CNN与迁移学习:从像素到预测的视觉智能工作流

1. 这不是魔法,是可拆解的视觉智能工作流 “From Pixels to Predictions”——这个标题里藏着过去十年计算机视觉最扎实的进化路径。它不是一句空泛的口号,而是描述了一个从原始图像数据出发,经过数学变换与模式提炼,最终输出结构…

2026/6/18 15:41:05阅读更多 →
Skill一键生成专业性能测试计划,7个Skill技能亲测好用,实现全链路压测落地(第二篇)

Skill一键生成专业性能测试计划,7个Skill技能亲测好用,实现全链路压测落地(第二篇)

一个真实场景周一早上,你收到业务方的压测需求:"双十一要来了,帮我们测一下订单提交接口,目标并发 5000。"你打开 JMeter,开始新建测试计划。并发填 5000,Ramp-up 填多少?你犹豫了一下…

2026/6/18 16:36:27阅读更多 →
【OpenCV实战】单目相机 + 条纹结构光三维重建:从条纹图到点云

【OpenCV实战】单目相机 + 条纹结构光三维重建:从条纹图到点云

前言单目相机本身只能获取二维图像,无法直接得到真实深度信息。 如果想用单个相机做三维重建,常见做法是引入主动光源,比如投影仪投射条纹图案。这种方法通常称为:结构光三维重建其中,投影仪投射编码条纹,单…

2026/6/18 16:36:27阅读更多 →
BeesFPD为什么能自动生成消防图纸?核心不是规则库,而是图形理解

BeesFPD为什么能自动生成消防图纸?核心不是规则库,而是图形理解

很多人以为BeesFPD能自动出消防图纸,是因为内置了一套庞大的规范规则库。错了。规则库谁都能买,但看不懂图纸,规则就没东西可匹配。什么是BeesFPD的生成能力?BeesFPD是图形大模型在机电/消防设计领域的应用产品,它能从…

2026/6/18 16:36:27阅读更多 →
英雄联盟Akari助手:从青铜到王者的终极游戏效率提升指南

英雄联盟Akari助手:从青铜到王者的终极游戏效率提升指南

英雄联盟Akari助手:从青铜到王者的终极游戏效率提升指南 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为每次游戏前的繁琐设…

2026/6/18 16:36:27阅读更多 →
Python 练习题讲解 3 · 字符串

Python 练习题讲解 3 · 字符串

一、选择题1. len():返回可迭代对象中的可迭代元素个数(也就是可迭代对象的长度)2. index():查找可迭代对象中第一个匹配的元素,并返回其对应的索引号,如果找不到抛出 ValueError 错误3. count()&#xff1…

2026/6/18 16:36:27阅读更多 →
Grok与SuperGrok技术解析:实时数据闭环、MoE架构与国内实操指南

Grok与SuperGrok技术解析:实时数据闭环、MoE架构与国内实操指南

1. Grok不是另一个聊天框,它是马斯克团队塞进AI壳子里的“直球型技术伙伴” 你有没有试过问一个AI问题,它先绕三圈、打两套官话、再加三句免责声明,最后才敢说半句真话?Grok从第一天上线就反着来——它不回避争议,不粉…

2026/6/18 16:31:25阅读更多 →
ZigBee HA智能家居开发实战:从集群模型到NXP JN516x代码实现

ZigBee HA智能家居开发实战:从集群模型到NXP JN516x代码实现

1. ZigBee HA:智能家居的“通用语言”与开发基石如果你正在或计划踏入智能家居设备开发领域,尤其是基于ZigBee协议,那么“ZigBee Home Automation”这个名词你一定不陌生。它不仅仅是ZigBee联盟定义的一套应用层规范,更是确保不同…

2026/6/18 0:00:24阅读更多 →
Java毕设选题推荐:基于 Spring Boot 的个人随笔博客运维管理系统的设计与实现 基于 Spring Boot 的用户原创博客分享社区【附源码、mysql、文档、调试+代码讲解+全bao等】

Java毕设选题推荐:基于 Spring Boot 的个人随笔博客运维管理系统的设计与实现 基于 Spring Boot 的用户原创博客分享社区【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/6/18 0:00:24阅读更多 →
JN517x嵌入式开发实战:看门狗、脉冲计数器与I2C接口的深度解析与避坑指南

JN517x嵌入式开发实战:看门狗、脉冲计数器与I2C接口的深度解析与避坑指南

1. 项目概述在嵌入式开发领域,尤其是基于NXP JN517x这类无线微控制器的项目中,系统稳定性和与外设的可靠交互是两大核心挑战。前者关乎产品能否在无人值守的复杂环境中长期运行,后者则决定了设备能否准确感知世界并与其他芯片“对话”。JN517…

2026/6/18 0:00:24阅读更多 →