c3p0数据库连接池的三种配置方式(java代码、xml文件、properties文件)

数据库连接池

JDBC开发流程

  • 加载驱动(只加载一次)
  • 获取数据库连接(Connection)
  • 执行 SQL 语句(Statement)
  • ResultSet 接收结果集
  • 断开连接,释放资源

数据库连接对象是通过 DriverManager 得到的,每次获取都要向数据库申请获取连接,并验证用户名、密码,执行完 SQL 语句后,断开连接,这样的方式会造成资源的浪费,因为连接对象只使用了一次就释放掉了,下一次连接还要继续向数据库申请,相当于用一部手机打电话,打了一通电话就把手机扔掉了,需要下一次通话时,在买一部,然后在打,资源没有得到很好的利用。

为了解决这一问题,数据库连接池出现了,其基本思想是为数据库建立一个连接池,预先向连接池存入一些连接对象,当需要获取连接时,只需要从连接池中取出一个连接,用完之后在放回到池中,供下一次连接继续使用,这样资源就得到了很好的复用,使一个连接对象可以被重复的使用,而不需要重新创建。

当数据库连接池中没有多余的连接对象时,线程就会进入等待状态,等待其它线程释放连接对象后在使用。

连接池的实现

JDBC 数据库连接池是使用 javax.sql.DataSource 接口来实现的,是由 java 官方提供的,连接池是一种思想,接口是一种抽象的功能,具体的实现还是得自己写。但是如果是自己写连接池的话,太麻烦,需要自己写底层代码,所以我们可以使用第三方写好的工具。

常用的第三方连接池工具:c3p0、dhcp等

使用 c3p0 工具,有三种实现方法:

  1. 通过硬编码方式设置驱动类及用户名、密码等。

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            // 创建 ComboPooledDataSource 对象,该对象间接实现了 java 官方提供的 DataSource 接口
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setDriverClass("org.mariadb.jdbc.Driver");
            comboPooledDataSource.setJdbcUrl("jdbc:mariadb://localhost:3306/dbtest?useUnicode=true&characterEncoding=UTF-8");
            comboPooledDataSource.setUser("root");
            comboPooledDataSource.setPassword("password");
            // 设置初始化连接数
            comboPooledDataSource.setInitialPoolSize(20);
            // 设置最小连接数,当连接池还有2个的时候,就开始申请连接数
            comboPooledDataSource.setMinPoolSize(2);
            // 设置最大连接数,最多只能有 40 个连接
            comboPooledDataSource.setMaxPoolSize(40);
            // 当连接数不够用时,一次向数据库申请多少个连接
            comboPooledDataSource.setAcquireIncrement(5);
            // 只是对连接做了优化,剩下的操作不变
            String sql = "select * from student";
            connection = comboPooledDataSource.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                Integer id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                Double score = resultSet.getDouble(3);
                Date birthday = resultSet.getDate(4);
                System.out.println(id + name + score + birthday);
            }
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        } catch (SQLException e){
            e.printStackTrace();
        } finally {
            try {
                resultSet.close();
                preparedStatement.close();
                // 这里并不是把连接关闭了,而是释放到连接池里,等待下一次继续使用
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    
  2. 通过 xml 配置文件设置

    c3p0-config.xml:

    ​ 文件名是固定的,放在 src 根目录下

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
            <!-- 数据库驱动名 -->
            <property name="driverClass">org.mariadb.jdbc.Driver</property>
            <!-- 数据库的url -->
            <!-- 在 xml 文件中,& 符号需要进行转义,使用 &amp; 来代替 & -->
            <property name="jdbcUrl">jdbc:mariadb://localhost:3306/dbtest?useUnicode=true&amp;characterEncoding=UTF-8</property>
            <property name="user">root</property>
            <property name="password">password</property>
            <!--初始化连接数,取值应在minPoolSize与maxPoolSize之间 -->
            <property name="initialPoolSize">20</property>
            <!--当连接池中的连接耗尽的时候 c3p0 一次同时获取的连接数 -->
            <property name="acquireIncrement">5</property>
            <!-- 设置最小连接数,当连接池还有2个的时候,就开始申请连接数-->
            <property name="minPoolSize">2</property>
            <!-- 设置最大连接数,最多只能有 40 个连接-->
            <property name="maxPoolSize">40</property>
            <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
            <property name="acquireRetryAttempts">30</property>
            <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
            <property name="acquireRetryDelay">1000</property>
            <!--连接关闭时默认将所有未提交的操作回滚。Default: false -->
            <property name="autoCommitOnClose">false</property>
            <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
            <property name="idleConnectionTestPeriod">0</property>
            <!-- 连接超时时间, default: 0。如果是0,表示无限等待 -->
            <property name="checkoutTimeout">0</property>
        </default-config>
        
        <named-config name="testc3p0">
        	... ...
        </named-config>
    </c3p0-config>
    

    java 文件:

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            /**
            * 这个方法提供一个无参构造,一个有参构造
            * 无参构造默认读取配置文件中的 <default-config> 节点中的内容
            * 有参构造读取 <named-config name="testc3p0"> 节点中的内容,传入的参数为 name 的 value
            */
            // 无参构造
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            //有参构造
            //ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("testc3p0");
            connection = comboPooledDataSource.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                Integer id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                Double score = resultSet.getDouble(3);
                Date birthday = resultSet.getDate(4);
                System.out.println(id + name + score + birthday);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                resultSet.close();
                preparedStatement.close();
                // 这里并不是把连接关闭了,而是释放到连接池里,等待下一次继续使用
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    
  3. 使用 properties 配置文件

    c3p0 会自动解析 properties 文件

    c3p0.properties:

    ​ 文件名固定,也是放到 src 目录下

    c3p0.driverClass=org.mariadb.jdbc.Driver
    c3p0.jdbcUrl=jdbc:mariadb://localhost:3306/dbtest?useUnicode=true&characterEncoding=UTF-8
    c3p0.user=root
    c3p0.password=password
    
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            connection = comboPooledDataSource.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                Integer id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                Double score = resultSet.getDouble(3);
                Date birthday = resultSet.getDate(4);
                System.out.println(id + name + score + birthday);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                resultSet.close();
                preparedStatement.close();
                // 这里并不是把连接关闭了,而是释放到连接池里,等待下一次继续使用
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

很简单_

点个赞在走呗 ~~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值