java学习笔记41(数据库连接池 C3p0连接池)

时间:2022-06-11 11:49:25

在之前的学习中,我们发现,我们需要频繁的创建连接对象,用完之后还需要在关闭资源,因为这些连接对象都是占资源的,但是又不得不创建,比较繁琐,为了解决这种情况,Java出现了数据库连接池;

数据库连接池的概念:

  定义:本质上就是一个容器(集合,java没有容器)用来存放数据库连接的内容,当系统初始化以后,容器被创建,容器中就会申请一些连接对象,当用户来访问数据库的时候,从容器中取出对象,用完之后归还。

通俗理解连接池:就像一个饭店,本来是来一个客人就招一个服务员,然后客人走后,服务员就被辞退,下次再来客人就再招一个服务员,然后用了连接池以后就像是招了好几个服务员在一个屋里等着,来一个客人就派一个服务员去接待,客人走后服务员在回到屋内。数据库连接池就是这样,连接池里有若干个连接对象, 需要时就拿去用, 用完后归还连接。

数据库的连接池有好多种,我们今天学习C3p0连接池,

需要导入的jar包有:

  c3p0-0.9.5.2.jar

   mchange-commons-java-0.2.12.jar

   mysql-connector-java-5.1.45-bin.jar

jar包放入lib文件夹,导jar包的方法在之前写过,这里就不介绍了

C3p0连接池需要配置外部文件,注意:文件名必须是  c3p0.properties 或 c3p0-config.xml  必须放在src文件夹下

这里是写的c3p0-config.xml配置文件,代码如下:

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
      <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/qy97</property>
    <property name="user">root</property>
    <property name="password">123456</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">10</property>
    <property name="checkoutTimeout">3000</property>
  </default-config>

    <!--另一个连接池-->
  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/mybase</property>
    <property name="user">root</property>
    <property name="password">123456</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

连接池的用法:

package com.zs.cp30;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/*创建出c3p0连接池*/
public class C3p0Demo {
    public static void main(String[] args) throws SQLException {
//    1.导入两个包 c3p0-0.9.5.2.jar  mchange-commons-java-0.2.12.jar
//    2.创建连接池核心对象,数据库连接池对象ComboPooledDataSource\
        DataSource ds=new ComboPooledDataSource();
//    3.获取连接
        Connection conn=ds.getConnection();
//        4.输出连接地址,查看是否连接成功
        System.out.println(conn);
    }
}

在之前的配置文件种,我们写了最大连接数是10个,现在我们来获得这十个连接:

package com.zs.cp30;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3p0Demo1 {
    public static void main(String[] args) throws SQLException {
        DataSource ds=new ComboPooledDataSource();

        for (int i = 1; i <= 10; i++) {
            Connection conn = ds.getConnection();
            System.out.println(conn);
        }
    }
}
/*结果:
com.mchange.v2.c3p0.impl.NewProxyConnection@7a419da4 [wrapping: com.mysql.jdbc.JDBC4Connection@14555e0a]
com.mchange.v2.c3p0.impl.NewProxyConnection@759d26fb [wrapping: com.mysql.jdbc.JDBC4Connection@3c73951]
com.mchange.v2.c3p0.impl.NewProxyConnection@6f46426d [wrapping: com.mysql.jdbc.JDBC4Connection@73700b80]
com.mchange.v2.c3p0.impl.NewProxyConnection@10d307f1 [wrapping: com.mysql.jdbc.JDBC4Connection@4d5b6aac]
com.mchange.v2.c3p0.impl.NewProxyConnection@4a7f959b [wrapping: com.mysql.jdbc.JDBC4Connection@429bffaa]
com.mchange.v2.c3p0.impl.NewProxyConnection@483f6d77 [wrapping: com.mysql.jdbc.JDBC4Connection@7e5afaa6]
com.mchange.v2.c3p0.impl.NewProxyConnection@28f3b248 [wrapping: com.mysql.jdbc.JDBC4Connection@1b1426f4]
com.mchange.v2.c3p0.impl.NewProxyConnection@581ac8a8 [wrapping: com.mysql.jdbc.JDBC4Connection@6d4e5011]
com.mchange.v2.c3p0.impl.NewProxyConnection@76c3e77a [wrapping: com.mysql.jdbc.JDBC4Connection@78123e82]
com.mchange.v2.c3p0.impl.NewProxyConnection@fba92d3 [wrapping: com.mysql.jdbc.JDBC4Connection@662b4c69]*/

在上面我们可以看出,10个连接对象,都不相同,这时,连接池内所有的连接对象都被取出来了,当取第11个对象时,就会报错:

public class C3p0Demo1 {
    public static void main(String[] args) throws SQLException {
        DataSource ds=new ComboPooledDataSource();

        for (int i = 1; i <= 11; i++) {
            Connection conn = ds.getConnection();
            System.out.println(conn);
        }
    }
}

上面的 代码会报错,因为没有第十一个连接对象,那么我们在循环种还回去一个连接对象,那么就不会报错了:

package com.zs.cp30;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3p0Demo1 {
    public static void main(String[] args) throws SQLException {
        DataSource ds=new ComboPooledDataSource();

        for (int i = 1; i <= 11; i++) {
            Connection conn = ds.getConnection();
            System.out.println(conn);
            if (i==5) {
                conn.close();
            }
        }
    }
}
/*结果:
com.mchange.v2.c3p0.impl.NewProxyConnection@7a419da4 [wrapping: com.mysql.jdbc.JDBC4Connection@14555e0a]
com.mchange.v2.c3p0.impl.NewProxyConnection@759d26fb [wrapping: com.mysql.jdbc.JDBC4Connection@3c73951]
com.mchange.v2.c3p0.impl.NewProxyConnection@6f46426d [wrapping: com.mysql.jdbc.JDBC4Connection@73700b80]
com.mchange.v2.c3p0.impl.NewProxyConnection@10d307f1 [wrapping: com.mysql.jdbc.JDBC4Connection@4d5b6aac]
com.mchange.v2.c3p0.impl.NewProxyConnection@4a7f959b [wrapping: com.mysql.jdbc.JDBC4Connection@429bffaa]
com.mchange.v2.c3p0.impl.NewProxyConnection@28f3b248 [wrapping: com.mysql.jdbc.JDBC4Connection@1b1426f4]
com.mchange.v2.c3p0.impl.NewProxyConnection@581ac8a8 [wrapping: com.mysql.jdbc.JDBC4Connection@6d4e5011]
com.mchange.v2.c3p0.impl.NewProxyConnection@76c3e77a [wrapping: com.mysql.jdbc.JDBC4Connection@429bffaa]
com.mchange.v2.c3p0.impl.NewProxyConnection@67c33749 [wrapping: com.mysql.jdbc.JDBC4Connection@fba92d3]
com.mchange.v2.c3p0.impl.NewProxyConnection@fa49800 [wrapping: com.mysql.jdbc.JDBC4Connection@71238fc2]
com.mchange.v2.c3p0.impl.NewProxyConnection@16a0ee18 [wrapping: com.mysql.jdbc.JDBC4Connection@3d6f0054]*/

注意上面结果中红色标识的两个连接对象,可以看出这两个是一个对象,也就是这个对象被调用了两次,连接对象用完要及时归还,在连接池中,为了方便也用close 方法,不过此时表示的是归还对象,并不是释放资源。

 

用完要及时归还。