在之前的学习中,我们发现,我们需要频繁的创建连接对象,用完之后还需要在关闭资源,因为这些连接对象都是占资源的,但是又不得不创建,比较繁琐,为了解决这种情况,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 方法,不过此时表示的是归还对象,并不是释放资源。
用完要及时归还。