【JDBC】连接池介绍和druid连接池使用

一、连接池

连接是可以复用的,但是我们每次数据库操作,其实我们都是把连接给close掉了,接下来我们要做的事就是把连接复用起来,复用连接不仅是提升性能,也提升程序的响应时间,接下来我们用连接池的技术把连接复用起来。

image-20240725212241062


二、数据库连接池作用

总结缺点:

  1. 不使用数据库连接池,每次都通过 DriverManager 获取新连接,用完直接抛弃断开,连接的利用率太低,太浪费。
  2. 对于数据库服务器来说,压力太大了。我们数据库服务器和 Java 程序对连接数也无法控制,很容易导致数据库服务器崩溃。

我们就希望能管理连接。

  • 我们可以建立一个连接池,这个池中可以容纳一定数量的连接对象。一开始,我们可以先帮用户创建好一些连接对象,用户要拿连接对象时,就直接从池中拿,而不是新建了。这样也可以节省时间。用完后,放回去,别人可以接着用。
  • 可以提高连接的使用率。池中的用的有的连接用完了,那么连接池可以向服务器申请新的连接放到池中。
  • 直到池中的连接达到“最大连接数”,就不能再申请新的连接了,如果没有拿到连接的用户只能等待。

三、市面常见连接池产品和对比

连接池是一套JAVA提供的标准,在这个标准下,谁都可以实现。

java.sql.DataSource接口,这个接口里面规范了连接池获取连接的方法、规范了连接池回收连接的方法,不管是什么连接池,都得使用 DataSource = 第三方连接池的实现;

JDBC 的数据库连接使用 javax.sql.DataSource 接口进行规范,所有的第三方连接池都实现此接口,省了添加具体实现!也就是说,所有连接池获取连接的和回收连接方法都一样,不同的只有性能和扩展功能!

  • DBCP 是 Apache 提供的数据库连接池,速度相对 c3p0 较快,但因自身存在 BUG
  • C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以
  • Proxool 是 sourceforge 下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较 c3p0 差一点
  • Druid 是阿里提供的数据库连接池,据说是集 DBCP、C3P0、Proxool 优点于一身的数据库连接池,妥妥国货之光!!!

mock 性能数据(单位: ms)

52050100
tomcat-jdbc4424471,0131,264
c3p04,4805,5277,44910,725
dbcp6766898671,292
hikari38333830
druid291293562985

功能对比

功能dbcpdruidc3p0tomcat-jdbcHikariCP
是否支持 PSCache
监控jmxjmx/log/httpjmx,logjmxjmx
扩展性
sql 监控及解析支持
代码简单中等复杂简单简单
更新时间2015.8.62015.10.102015.12.092015.12.3
特点依赖于 common-pool阿里开源,功能全面历史久远,代码逻辑复杂,且不易维护优化力度大,功耗低boneCP
连接池管理LinkedBlockingDeque数组FairBlockingQueuethreadlocal+ConcurrentBag

通过性能与扩展性的对比,最终选择使用druid连接池。


四、国货之光 druid 连接池使用

druid连接池是第三方的,需要导入 druid 工具类 jar

可以发现,DruidDataSource也实现了DataSource接口,这就叫做连接池对象。

image-20240726092133579

硬编码方式(了解,不推荐)

1. 创建一个druid连接池对象
2. 设置连接池参数 [必须 | 非必须]
3. 获取连接 [通用方法, 所有连接池都一样]
4. 回收连接 [通用方法, 所有连接池都一样]
package com.atguigu.api.druid;

import com.alibaba.druid.pool.DruidDataSource;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;

public class DruidUsePart {
    /**
     * 创建druid连接池对象,使用硬编码进行核心参数设置!
     * 必须参数: 连接数据库驱动类的全限定符,用于注册驱动
     *          账号
     *          密码
     *          url
     *          driverClass,这个是我们驱动的地址
     * 非必须参数:
     *          初始化数量
     *          最大数量、等待时间等等  不推荐设置,因为你掌握不好它的一个度,不设置它也是有默认值的
     *
     */
    @Test
    public void druidHard() throws SQLException {

        // 注册驱动和创建连接的工作都交给了druid连接池做
        DruidDataSource dataSource = new DruidDataSource();

        // 设置四个必须参数,这四个参数设置好了后,它就能根据我们的信息帮我们完成驱动注册和获取文件
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setUrl("jdbc:mysql:///day01");
        
        // 非必须
        // 设置初始化连接数量
        dataSource.setInitialSize(5);
        // 设置最大连接数量
        dataSource.setMaxActive(10);
        // 设置等待时间
        dataSource.setMaxWait(3000);

        // 通过连接池获取连接
        // DruidPooledConnection connection = dataSource.getConnection();
        // PS:它返回的是包装的DruidPooledConnection,但DruidPooledConnection是实现了Connection接口的,所以这里我们可以直接使用Connection接收
        Connection connection = dataSource.getConnection();
        // JDBC的步骤
        // 回收连接
        connection.close(); // 如果是连接池调用close,那就是回收连接。因为我们刚刚看见了,我们拿到的这个connection其实不是原来的connection了,它其实是一个包装类,它里面做了优化,当你调用close方法后,是回收连接,即放回到连接池
    }
}

image-20240726081226509

硬编码是在Java代码中去设置这些参数,这一旦设置好后,程序运行起来后是无法修改的,这就叫硬编码。


软编码方式

外部配置 存放在 src/druid.properties

# key = value => java Properties??(key | value)
# druid连接池需要的配置参数,key必须固定命名
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=123456
url=jdbc:mysql://localhost:3306/itcast

druid 声明代码

/**
 * 不直接在java代码编写配置文件,利用工厂模式,传入配置文件对象,创建连接池!
 * @throws Exception
 */
@Test
public void druidSoft() throws Exception {
    //1.读取外部配置文件 Properties
    Properties properties = new Properties();
    //src下的文件可以使用类加载器提供的方法,路径是相对于src来说的
    InputStream ips = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
    properties.load(ips);
    // 根据properties对象,去创建一个连接池对象
    DataSource dataSource = DataSourceFactory.createDataSource(properties);
}

druid 配置(了解)

/**
 * 通过读取外部配置文件的方法,实例化druid连接池对象
 * 不直接在java代码编写配置文件,利用工厂模式,传入配置文件对象,创建连接池!
 * @throws Exception
 */
@Test
public void druidSoft() throws Exception {
    Properties properties = new Properties();
    InputStream ips = DruidUsePart.class.getClassLoader().getResourceAsStream("druid.properties");
    properties.load(ips);
    // 根据properties对象,利用连接池的工具类的工厂模式,去创建一个连接池对象
    DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);

    // 获取连接
    Connection connection = dataSource.getConnection();

    // 回收连接
    connection.close();
}

这样做的好处是:我们可以通过修改外部配置文件,进而去影响连接池相关的属性。


五、druid源码

这里解释一下为什么这些key需要固定命名。

硬编码中,我们是直接new的druid连接池,new完后直接设置属性

DruidDataSource dataSource = new DruidDataSource();

软编码中,我们不是直接new,而是通过工厂,工厂底层其实也是new

image-20240726101122377

往下滑,就可以看见我们刚刚设置的必须参数了

image-20240726101324798
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值