DataBase | 02 数据库连接池

数据库连接池

1. 数据库连接池的基本概念

1.1 过去的使用方式

每次进行SQL操作前从系统底层获取连接资源,执行结束后释放连接

问题:浪费资源同时获取资源的时间长

解决方式:使用数据库连接池这种获取连接的新方式

1.2 数据库连接池的本质

数据库连接池基本思想是为数据库连接建立一个容器(Java中即集合)

这个容器负责分配、管理和释放数据库连接,实质上提供了一种获取连接的新方式

1.3 数据库连接池的工作方式

  • 系统初始化好后,容器被创建,容器会申请一些连接对象

  • 当用户访问数据库时从容器中获取连接对象

  • 当用户访问完成后,将连接对象归还给容器( 不再需要用户释放 )

1.4 数据库连接池的优势

  • 节约资源,申请的连接可以重复使用

  • 访问高效,直接获取创建好的连接而不用从系统底层获取资源

  • 统一的连接管理,可以避免出现数据库连接泄漏的问题

2. 数据库连接池的使用

2.1 基本使用步骤

  1. 导入jar包
  2. 配置连接池
  3. 加载配置信息
  4. 创建核心数据库连接池对象
  5. 获取连接
  6. 后续与JDBC处理相同

小心别掉坑:在导入jar包时,连接池中的连接也是由驱动创建的所以驱动的jar包也要导入

Tips 2.1:配置连接的两种方式

以C3P0为例

编码的方式:初始化连接池对象,使用方法传入连接参数

set

//编码方式
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///dbtest");
dataSource.setUser("root");
dataSource.setPassword("1234");

配置的方式:在配置文件中设置连接的参数(常用

<!--配置方式-->
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///dbtest</property>
<property name="user">root</property>
<property name="password">1234</property>

Tips 2.2:连接池参数

以C3P0为例

  • initialPoolSize:初始化时申请的连接数量,后续连接数量不足可以增加但不可超过最大连接数量
  • maxPoolSize:连接池中的最大连接数量,超出后申请请求会进入等待队列直到有其他进程归还连接
  • checkoutTimeout:获取连接超时时间,超过该时间会失败报错,毫秒为单位

3. 数据库连接池技术实现

3.1 标准接口

Interface DataSource:数据源工厂

实现功能:

  1. 获取连接

    方法:
    在这里插入图片描述

  2. 归还连接:

    方法:和关闭连接使用相同的方法

    Tips:当连接是由连接池获取的close方法不再是关闭连接而是归还连接

3.2 具体实现

Tips:一般不自己编写标准接口DataSource的实现类由数据库厂商提供

3.2.1 C3P0
3.2.1.1 C3P0的基本使用
  • C3P0配置文件( c3p0-config.xml )

Tips:注意配置文件的写法

<c3p0-config>
    <!--默认配置-->
    <default-config>
        <!--连接信息-->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///dbtest</property>
        <property name="user">root</property>
        <property name="password">1234</property>
        <!--连接池配置参数-->
        <!--不设置c3p0会有默认的设置-->
    </default-config>
    
    <!--指定配置,方便配置多个连接池-->
    <!--name的值是配置的标识-->
    <named-config name="other">
        <!--连接信息-->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///dbtest</property>
        <property name="user">root</property>
        <property name="password">1234</property>
        <!--连接池配置参数-->
        <!--初始化时申请的连接数量后续可以增加但不可超过最大连接数量-->
        <property name="initialPoolSize">5</property>
        <!--连接池中可以申请的最大连接数量-->
        <property name="maxPoolSize">10</property>
        <!--获取连接超时时间,超过该时间会失败报错,毫秒为单位-->
        <property name="checkoutTimeout">1000</property>
    </named-config>
</c3p0-config>
  • C3P0的使用代码
//使用默认的配置创建连接池
public class C3P0Demo1 {
    public static void main(String[] args) {
        try {
            //创建数据库连接池
            //C3P0的连接池对象为ComboPooledDataSource
            DataSource dataSource = new ComboPooledDataSource();
            //获取连接
            Connection conn = dataSource.getConnection();
			//
            //之后与JDBC的使用方式相同
            //
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

//使用指定的配置创建连接池
public class C3P0Demo2 {
    public static void main(String[] args) {
        try {
            //使用名为"other"的配置创建连接池
            DataSource dataSource = new ComboPooledDataSource("other");
            //获取连接
            Connection conn = dataSource.getConnection();
            System.out.println(conn);
            //
            //之后与JDBC的使用方式相同
            //
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}


3.2.1.2 C3P0的不同点
  • C3P0会自动加载src目录下命名为c3p0.properties或c3p0-config.xml的配置文件
  • C3P0连接池的属性可以在控制台日志中查看

默认设置

  • C3P0的连接池对象为ComboPooledDataSource
3.2.2 Druid
3.2.2.1 Druid的基本使用
  • Druid的配置文件( druid.properties )
#连接信息
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///dbtest
username=root
password=1234
#连接池参数
#初始化申请的链接数量
initialSize=5
#最大的连接数量
maxActive=10
#最大获取连接等待时间
maxWait=1000
  • Druid的使用代码
public class DruidDemo1 {
    public static void main(String[] args) {
        try {
            //加载配置文件
            Properties prop = new Properties();
            //获取配置文件的字节输入流InputStream
            InputStream in = DruidDemo1.class
                .getClassLoader().getResourceAsStream("druid.properties");
            prop.load(in);
            //创建数据库连接池
            DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
            //获取连接
            Connection conn = dataSource.getConnection();
			//
            //之后与JDBC的使用方式相同
            //
        }catch(IOException e){
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
3.2.2.2 Druid的不同点
  • Druid配置文件为properties形式可以放在任意的目录下,需要手动加载配置
  • Druid的连接池对象通过工厂类方法( DruidDataSourceFactory.createDataSource( ) )获取

4. 数据库连接池工具类抽取

在JDBC工具类的基础上增加获取所使用连接池的方法

  • 工具类代码
public class JDBCUtil {
    private static DataSource dataSource;

    //使用静态代码块读取配置文件创建数据库连接池
    static{
        try {
            Properties prop = new Properties();
            prop.load(JDBCUtil.class.
                      getClassLoader().getResourceAsStream("druid.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(prop);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取创建的数据库连接池
    public static DataSource getDataSource(){
        return dataSource;
    }

    //从数据库连接池中获取连接
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException(throwables);
        }
    }

    //释放资源
    public static void close(ResultSet rs, Statement stmt, Connection conn){
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public static void close(Statement stmt,Connection conn){
        close(null,stmt,conn);
    }
}

Tips 4.1:对比JDBC的工具类

不再需要连接参数

private static String url;
private static String username;
private static String password;

这些参数都提供给了连接池,使用时获取连接池拿连接即可

private static DataSource dataSource;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值