数据库连接池技术与 Druid 连接工具类实现

目录

[1. 数据库连接池简介](#1. 数据库连接池简介)

[1.1. 什么是数据库连接池](#1.1. 什么是数据库连接池)

[1.2. 不使用数据库连接池可能存在的问题](#1.2. 不使用数据库连接池可能存在的问题)

[1.3. JDBC数据库连接池的必要性](#1.3. JDBC数据库连接池的必要性)

[1.4. 数据库连接池的优点](#1.4. 数据库连接池的优点)

[1.5. 常用的数据库连接池](#1.5. 常用的数据库连接池)

[2. Druid连接池](#2. Druid连接池)

[2.1. Druid简介](#2.1. Druid简介)

[2.2. Druid使用步骤](#2.2. Druid使用步骤)

[2.2.1. 第一步的步骤详解:](#2.2.1. 第一步的步骤详解:)

[2.2.2. 第二步的步骤详解:](#2.2.2. 第二步的步骤详解:)

[2.2.3. druid配置信息](#2.2.3. druid配置信息)

[2.3. 通过数据库连接池获取连接](#2.3. 通过数据库连接池获取连接)

[2.3.1. 获取读取druid配置的字节输入流](#2.3.1. 获取读取druid配置的字节输入流)

[2.3.2. 创建Properties对象](#2.3.2. 创建Properties对象)

[2.3.3. 加载配置文件](#2.3.3. 加载配置文件)

[2.3.4. 获取连接池对象](#2.3.4. 获取连接池对象)

[2.3.5. 获取连接](#2.3.5. 获取连接)

[3. 基于Druid连接池获取数据库连接工具类](#3. 基于Druid连接池获取数据库连接工具类)

[4. 总结](#4. 总结)


本文来讲解数据库地址池和Druid的配置使用以及使用JDBC来实现地址池

个人主页:艺杯羹

系列专栏:JDBC

1. 数据库连接池简介

1.1. 什么是数据库连接池

数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接 ,并将这些连接组成一个连接池,由程序动态地 对池中的连接进行申请,使用,释放

它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

当数据库连接空闲时间太长,超过了规定的最长空闲时长,就把这个连接释放掉

这样做是为了防止连接一直占着却没人用 ,要是不释放,就会出现连接浪费,也就是数据库连接遗漏的问题。通过这种方式,能大大提升对数据库操作的速度和效率

1.2. 不使用数据库连接池可能存在的问题

  • 连接建立耗时:用 DriverManager 获取连接,会加载 Connection、验证信息等过程耗时
  • 资源利用低效:按需建连、用完断开,连接无法复用,高并发时大量占用系统资源,可致服务器崩溃
  • 易引发内存泄漏:连接使用后若未断开,程序异常时会造成数据库内存泄漏,甚至需重启数据库

1.3. JDBC数据库连接池的必要性

  • 数据库连接池的基本思想: 为数据库连接建立一个"缓冲池"。预先 在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从"缓冲池"中取出一个,使用完毕之后再放回去
  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
  • 数据库连接池初始化按最小连接数创建连接并维持,最大连接数限制连接总量,超量请求排队等待

简单来说就是

数据库连接池就像个连接 "仓库"。程序启动时,在池里备好一定数量的连接。要用连接的时候从池里拿,用完后再放回去。它能够做连接的分配、管理和释放的工作,还通过设定最小、最大连接数来保障连接数量合理

1.4. 数据库连接池的优点

  1. 资源重用(连接复用,减少创建开销)

  2. 更快的系统反应速度(现成的连接,响应耗时短)

  3. 新的资源分配手段(按需要的多少分配,控连接数量)

  4. 统一的连接管理(集中管控,规范连接操作)

1.5. 常用的数据库连接池

这里介绍三款数据库连接池

  • c3p0:是一个开源组织提供的数据库连接池,速度相对较慢,稳定性还可以
  • DBCP:是Apache提供的数据库连接池。速度相对c3p0较快,但自身存在bug
  • Druid:是阿里提供的数据库连接池,据说是集DBCP、c3p0优点于一身的数据库连接池,目前经常使用

所以接下来使用Druid连接池来实现功能

2. Druid连接池

2.1. Druid简介

Druid是阿里提供的数据库连接池,它结合了C3P0、DBCP等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况

2.2. Druid使用步骤

  1. 导入druid-1.2.8.jar包到lib目录下,并引入到项目中

  2. src 下创建一个druid.properties 类型的文件,并写入

    复制代码
    url=jdbc:mysql://localhost:3306/mytest?useSSL=false
    driverClassName=com.mysql.jdbc.Driver
    username=root
    password=root
    initialSize=10
    maxActive=20

这个url要配置自己的数据库名称

如果不知道怎么配置,我之前写过一篇文章,里面讲过

传送门:数据库连接 (* ̄︶ ̄)

2.2.1. 第一步的步骤详解:

本文最前面有druid-1.2.8.jar的压缩包可以免费下载😊,下载后解压即可

再复制这个压缩到,回到idea,单击lib目录 ---> Ctrl + v 复制

确定即可

2.2.2. 第二步的步骤详解:

新建 ---> 文件 ---> 输入:druid.properties ---> 里面再写入要写入的数据即可

2.2.3. druid配置信息

druid配置信息的参数,也就是刚刚要在druid.properties中写的配置项

配置项 说明
name 用于区分多个数据源,未配置则自动生成特定格式名字
url 连接数据库的地址
username 连接数据库的用户名
password 连接数据库的密码
driverClassName 可自行配置,也可由 druid 根据 url 自动识别驱动类型,建议配置
initialSize 初始化时创建的物理连接数量
maxActive 连接池允许的最大连接数量
minIdle 连接池保持的最小连接数量
maxWait 获取连接时的最大等待时间(毫秒),配置后默认启用公平锁,可配非公平锁
poolPreparedStatements 是否缓存 preparedStatement,对部分数据库性能提升大,mysql 下建议关闭
maxOpenPreparedStatements 启用 PSCache 需配置大于 0,此时 poolPreparedStatements 自动为 true,Druid 中可配较大值
validationQuery 检测连接有效性的 sql 查询语句,为 null 时相关检测失效
testOnBorrow 申请连接时检测连接有效性,会降低性能
testOnReturn 归还连接时检测连接有效性,会降低性能
testWhileIdle 建议配置为 true,不影响性能且保证安全性,空闲超一定时间检测
timeBetweenEvictionRunsMillis 检测连接的间隔时间,也是 testWhileIdle 判断依据
numTestsPerEvictionRun 不再使用
minEvictableIdleTimeMillis 无明确说明
connectionInitSqls 物理连接初始化时执行的 sql
exceptionSorter 数据库抛不可恢复异常时,据此抛弃连接
filters 通过别名配置扩展插件,如监控、日志、防 sql 注入插件
proxyFilters 与 filters 为组合关系

标红是常用的配置项

2.3. 通过数据库连接池获取连接

2.3.1. 获取读取druid配置的字节输入流

java 复制代码
InputStream is = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");

2.3.2. 创建Properties对象

java 复制代码
Properties pos = new Properties();

2.3.3. 加载配置文件

java 复制代码
pos.load(is);

2.3.4. 获取连接池对象

java 复制代码
DataSource ds = DruidDataSourceFactory.createDataSource(pos);

2.3.5. 获取连接

java 复制代码
Connection connection = ds.getConnection();

数据库连接池获取连接完整代码

java 复制代码
public class DruidTest {
  public static void main(String[] args) throws Exception {
    // 获取读取druid配置的字节输入流
    InputStream is = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");
    // 创建Properties对象
    Properties pos = new Properties();
    // 加载配置文件
    pos.load(is);
    // 获取连接池对象
    DataSource ds = DruidDataSourceFactory.createDataSource(pos);
    // 获取连接
    Connection connection = ds.getConnection();
    // 输出测试,是否获取到了connection
    System.out.println(connection);
   }
}

3. 基于Druid连接池获取数据库连接工具类

在刚开始讲过JDBC的连接工具类

那么连接池也可以抽取一个工具来使用,这样对于后序的操作更方便实现

因为之前讲过JDBC的连接工具类,连接池的也差不多,就直接给出实现代码了

java 复制代码
public class JdbcDruidUtil {
   //数据库连接池对象
   private static DataSource dataSource;
   static{
     try {
       // 获取读取配置文件的字节输入流对象
       InputStream is = JdbcDruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
       // 创建Properties对象
       Properties pop = new Properties();
       // 加载配置文件
       pop.load(is);
       // 创建连接池对象
       dataSource = DruidDataSourceFactory.createDataSource(pop);
     }catch(Exception e){
       e.printStackTrace();
     }
   }
  // 获取数据库连接对象
  public static Connection getConnection(){
    Connection connection = null;
    try {
      connection = dataSource.getConnection();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
    return connection;
   }
  // 关闭连接对象
  public static void closeConnection(Connection connection){
    try {
      connection.close();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
   }
  // 提交事务
  public static void commit(Connection connection){
    try {
      connection.commit();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
   }
  // 事务回滚(撤销)
  public static void rollback(Connection connection){
    try {
      connection.rollback();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
   }
  // 关闭Statement对象
  public static void closeStatement(Statement statement){
    try {
      statement.close();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
   }
  // 关闭ResultSet
  public static void closeResultSet(ResultSet resultSet) {
    try {
      resultSet.close();
     } catch (SQLException throwables) {
      throwables.printStackTrace();
     }
   }
  // DML操作时关闭资源
  public static void closeResource(Statement statement,Connection connection){
    //先关闭Statement对象
    closeStatement(statement);
    //在关闭Connection对象
    closeConnection(connection);
   }
  // 查询时关闭资源
  public static void closeResource(ResultSet resultSet,Statement statement,Connection connection){
    // 先关闭ResultSet
    closeResultSet(resultSet);
    // 在闭Statement对象
    closeStatement(statement);
    // 最后关闭Connection对象
    closeConnection(connection);
   }
}

4. 总结

到现在为止,数据库地址池就讲解完毕了,接下里用一张思维导图来总结一下

希望能够帮助到大家😊

相关推荐
dianzouyou1234563 分钟前
钉钉报销与金蝶付款单系统对接技术揭秘
大数据·数据库·钉钉
初次见面我叫泰隆10 分钟前
MySQL——6、内置函数
数据库·mysql
CodeLinghu11 分钟前
宝塔面板部署前后端项目SpringBoot+Vue2
java·spring boot·后端
悟能不能悟14 分钟前
Spring Boot循环依赖的陷阱与解决方案:如何打破“Bean创建死循环”?
java·spring boot·spring
Zero two and hiro18 分钟前
tomcat一闪而过,按任意键继续以及控制台中文乱码问题
java·服务器·tomcat
Ultipa34 分钟前
云计算与大数据进阶 | 26、解锁云架构核心:深度解析可扩展数据库的5大策略与挑战(上)
大数据·数据库·云计算
纸包鱼最好吃37 分钟前
java基础-关键字:static、单例模式
java·开发语言
编程、小哥哥1 小时前
Java面试深度解析:微服务与云原生技术应用场景详解
java·spring cloud·微服务·云原生·面试·kubernetes·链路追踪
中国lanwp1 小时前
在Maven中替换文件内容的插件和方法
服务器·数据库·maven
菜菜小蒙1 小时前
【MySQL】内置函数
数据库·mysql