当前位置: 首页 > news >正文

数据库连接池(附 Druid 完整代码)

池化思想的特点:是一个容器,可以减少创建连接和销毁连接的频次,提高效率

一、为什么要用数据库连接池?

在没有连接池的时代,我们每次操作数据库都要:

  • 加载驱动

  • 创建连接

  • 执行 SQL

  • 销毁连接

而创建和销毁连接是非常耗时的操作,涉及网络通信、TCP 握手、权限校验等步骤,频繁创建会带来严重的性能开销,甚至导致数据库连接耗尽。

连接池的核心思想,就是「池化复用」:

  • 程序启动时,预先创建一批数据库连接,放在 “池子” 里统一管理

  • 业务代码需要连接时,直接从池子里取,用完再归还

  • 避免频繁创建和销毁连接,大幅提升性能,同时控制最大并发连接数,防止数据库被压垮

1.1 连接池概述

1.总结

  • 原来:需要自己创建连接和销毁连接,这样是比较消耗时间,资源等。

  • 现在:有一些连接池,已经创建好了一些连接,现在可以从连接池中获取到,这样就节省创建连接时间,直接使
    用这些连接,归还到连接池中。

  • 节省创建连接与释放连接,性能消耗

  • 连接池中连接起到复用的作用,提升程序性能

2.连接池(池参数,如果不指定,有默认值)

  • 初始大小:10个

  • 最小空闲连接数:3个

  • 增量:一次创建的最小单位(5个)

  • 最大空闲连接数:12个

  • 最大连接数:20个

  • 最大的等待时间:1000毫秒

3.4个参数:任何的开源的连接池,4大参数都需要自己来设置

  • 驱动的名称 ‐‐ com.mysql.jdbc.Driver

  • 连接 ‐‐ jdbc:mysql:///day14

  • 用户名 ‐‐ root

  • 密码 ‐‐ root

二、连接池的核心概念与参数

  1. 标准接口:DataSource
  • JDBC 规范定义了 javax.sql.DataSource 接口,所有开源连接池(包括 Druid、DBCP、C3P0)都必须实现这个接口。

  • 核心方法:getConnection(),业务代码通过这个方法从池子里获取连接

  • 连接池对 Connection 的 close() 方法做了增强:调用 conn.close() 时,并不是真正销毁连接,而是把连接归还到池子里,等待复用。

  1. 连接池的核心配置参数

不同连接池的参数略有差异,但核心配置基本一致:

参数 作用 示例
driverClassName 数据库驱动类全限定名 com.mysql.cj.jdbc.Driver
url 数据库连接地址 jdbc:mysql://localhost:3306/jdbcdemo?useSSL=false&serverTimezone=UTC
username 数据库用户名 root
password 数据库密码 root
initialSize 初始化连接数,启动时创建的连接数量 5
minIdle 最小空闲连接数,池子里始终保持的空闲连接数 3
maxActive 最大连接数,池子最多同时存在的连接数 10
maxWait 获取连接的最大等待时间(毫秒),超时会抛出异常 3000

三、主流连接池对比

目前 Java 生态中主流的连接池有 3 种:

  • DBCP:Apache 开源,老牌连接池,性能一般,功能简单

  • C3P0:老牌连接池,支持 JDBC3 标准,但并发性能较差

  • Druid:阿里巴巴开源,目前业界公认的最佳连接池

    • 高性能,并发场景下表现远超其他连接池

    • 内置强大的 SQL 监控、性能统计功能

    • 支持密码加密、SQL 日志、JDBC 扩展等高级特性

    • 已在阿里数百个生产环境大规模验证,稳定性极强

四、Druid 连接池实战(两种实现方式)

下面是 Druid 连接池的完整实现,分为硬编码和配置文件两种方式。

方式 1:硬编码实现(快速上手)

package cn.tx.demo1;import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class JdbcTest6 {public static void main(String[] args) {// 1. 创建 Druid 连接池对象DruidDataSource dataSource = new DruidDataSource();// 2. 设置数据库连接的 4 大核心参数dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/jdbcdemo?useSSL=false&serverTimezone=UTC");dataSource.setUsername("root");dataSource.setPassword("root");// 3. 设置连接池核心参数dataSource.setInitialSize(5);   // 初始化连接数dataSource.setMaxActive(10);     // 最大连接数dataSource.setMaxWait(2000);     // 获取连接超时时间(毫秒)Connection conn = null;PreparedStatement stmt = null;try {// 4. 从连接池获取连接conn = dataSource.getConnection();// 5. 编写 SQL 并执行String sql = "insert into t_user values (null, ?, ?, ?)";stmt = conn.prepareStatement(sql);stmt.setString(1, "eee");stmt.setString(2, "eee");stmt.setString(3, "eee");stmt.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {// 6. 释放资源:归还连接到池子if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {// 这里的 close() 不是销毁连接,而是归还到连接池conn.close();} catch (SQLException e) {e.printStackTrace();}}}}
}

方式 2:配置文件实现(生产环境推荐)

步骤 1:创建 druid.properties 配置文件

在 src/main/resources 目录下创建配置文件:

# 数据库连接配置
driverClassName=com.mysql.jdbc.Driver   //5.0版本的mysqljar包
//8.0版本的jar包用:driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo?useSSL=false&serverTimezone=UTC
username=root
password=root# 连接池配置
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

步骤 2:编写 JDBC 工具类

package cn.tx.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** 基于 Druid 连接池的 JDBC 工具类*/
public class JdbcUtils2 {// 连接池对象private static final DataSource DATA_SOURCE;static {Properties pro = new Properties();try {// 加载配置文件InputStream inputStream = JdbcUtils2.class.getResourceAsStream("/druid.properties");pro.load(inputStream);// 创建 Druid 连接池DATA_SOURCE = DruidDataSourceFactory.createDataSource(pro);} catch (Exception e) {throw new RuntimeException("初始化 Druid 连接池失败", e);}}/*** 从连接池获取连接* @return 数据库连接*/public static Connection getConnection() {try {return DATA_SOURCE.getConnection();} catch (SQLException e) {throw new RuntimeException("获取数据库连接失败", e);}}/*** 关闭资源(归还连接到池子)* @param conn 连接对象* @param stmt Statement 对象* @param rs 结果集*/public static void close(Connection conn, Statement stmt, ResultSet rs) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {// 归还连接到连接池conn.close();} catch (SQLException e) {e.printStackTrace();}}}/*** 重载方法:关闭无结果集的资源*/public static void close(Connection conn, Statement stmt) {close(conn, stmt, null);}
}

五、核心原理:为什么 conn.close() 不会真的销毁连接?

很多初学者会疑惑:调用 conn.close() 后,连接不是被关闭了吗?为什么连接池还能复用?

核心答案是:连接池对 Connection 对象做了增强(代理 / 装饰模式):

  1. 业务代码拿到的 Connection 不是原生的数据库连接,而是连接池包装后的代理对象
  2. 当调用 conn.close() 时,执行的是连接池重写后的逻辑:
    • 重置连接状态(回滚未提交事务、恢复自动提交等)
    • 把连接归还到池子里,标记为空闲状态
  3. 只有当连接池关闭、连接超时被清理时,才会真正调用原生连接的 close() 方法销毁连接

六、Druid 连接池的高级特性

  • SQL 性能监控:内置 StatFilter 插件,可统计每条 SQL 的执行耗时、并发次数,方便定位慢查询

  • 数据库密码加密:支持 PasswordCallback,避免明文密码泄露,提升安全性

  • SQL 日志记录:支持多种日志框架,可记录所有执行的 SQL,方便排查问题

  • JDBC 扩展:通过 Filter 机制,可自定义 JDBC 层的扩展逻辑,比如 SQL 拦截、数据脱敏等

http://www.jsqmd.com/news/672373/

相关文章:

  • 2026贝赛思备考辅导与课程同步辅导机构推荐,专业贝赛思课程辅导机构汇总 - 品牌2026
  • 如何平衡计算复杂度与实时性要求?
  • 终极指南:如何用ViGEmBus虚拟手柄驱动彻底解决Windows游戏兼容性问题
  • Whisky:macOS上运行Windows程序的终极免费方案
  • 2026年专业厨师切片刀哪个牌子好 国内主流刀具品牌选型深度解析 - 商业小白条
  • 打卡信奥刷题(3141)用C++实现信奥题 P7629 [COCI 2011/2012 #1] SORT
  • 音频智能切片终极指南:告别手动剪辑的完整解决方案
  • 从“占座”到防御:用Python模拟Slowloris攻击,并聊聊Web服务器(Nginx/Apache)该怎么配置才安全
  • 医院新生儿出生证明人证核验方案-打印A4核验信息表单 - 智能硬件-产品评测
  • Win11Debloat:专业级Windows系统优化与隐私保护完整解决方案
  • 如何高效使用fanqienovel-downloader:5个实用技巧快速构建个人离线小说库
  • GSE宏工具终极指南:快速掌握魔兽世界技能自动化的完整解决方案
  • 别再死记硬背公式了!用HEC-RAS 1D恒定流模拟,手把手教你理解能量方程与动量方程的区别
  • Memobase快速入门指南:5分钟搭建你的第一个用户配置文件
  • 2026年SAT一对一培训哪家好?专业机构及线下高端一对一课程推荐 - 品牌2026
  • Redis事务处理详解:确保数据一致性的关键策略
  • 简单三步实现Windows完美远程桌面连接Linux:xrdp终极指南
  • 手把手教你部署Qwen3-VL-8B:上传图片就能智能问答的AI助手
  • 别再只盯着GCN了!用Python+PyTorch复现ASTGCN,实测METR-LA数据集避坑指南
  • D3KeyHelper终极指南:如何用AutoHotkey打造暗黑3自动化战斗系统
  • G-Helper:如何用轻量级工具解决华硕笔记本的性能管理难题
  • 2026年4月万国官方售后网点亲测+避坑指南:实地横评与数据溯源报告(含迁址/新开)|老司机分享全流程记录 - 亨得利官方服务中心
  • Objectron开发者指南:如何扩展数据集支持新的物体类别
  • 如何将你的网页游戏变成专业桌面应用:Twine App Builder跨平台打包指南
  • 淘宝、1688 拍立淘(以图搜货)接口接入全解:从实战心得到落地教学
  • OWASP Nettacker高级配置技巧:硬件资源优化与性能调优终极指南
  • 3分钟上手!RPG Maker解密工具全攻略:轻松提取游戏资源的终极指南
  • React同构HTTP请求实战:use-http在Next.js中的完美应用
  • 构建极致性能:Voron 2.4 CoreXY架构3D打印机的5大创新设计
  • 3D-ResNets-PyTorch实战指南:7个关键技巧助你避开动作识别常见陷阱