java学习笔记41(数据库连接池 C3p0连接池)
在之前的学习中,我们发现,我们需要频繁的创建连接对象,用完之后还需要在关闭资源,因为这些连接对象都是占资源的,但是又不得不创建,比较繁琐,为了解决这种情况,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><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 连接池参数 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="initialPoolSize"</span><span style="color: rgba(0, 0, 255, 1)">></span>5<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="maxPoolSize"</span><span style="color: rgba(0, 0, 255, 1)">></span>10<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="checkoutTimeout"</span><span style="color: rgba(0, 0, 255, 1)">></span>3000<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span>
</default-config>
<span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)">另一个连接池</span><span style="color: rgba(0, 128, 0, 1)">--></span>
<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><span style="color: rgba(0, 128, 0, 1)"><!--</span><span style="color: rgba(0, 128, 0, 1)"> 连接池参数 </span><span style="color: rgba(0, 128, 0, 1)">--></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="initialPoolSize"</span><span style="color: rgba(0, 0, 255, 1)">></span>5<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="maxPoolSize"</span><span style="color: rgba(0, 0, 255, 1)">></span>8<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span> <span style="color: rgba(0, 0, 255, 1)"><</span><span style="color: rgba(128, 0, 0, 1)">property </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="checkoutTimeout"</span><span style="color: rgba(0, 0, 255, 1)">></span>1000<span style="color: rgba(0, 0, 255, 1)"></</span><span style="color: rgba(128, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">></span>
</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</span>
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();</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 1; i <= 10; i++<span style="color: rgba(0, 0, 0, 1)">) { Connection conn </span>=<span style="color: rgba(0, 0, 0, 1)"> 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();</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 1; i <= 11; i++<span style="color: rgba(0, 0, 0, 1)">) { Connection conn </span>=<span style="color: rgba(0, 0, 0, 1)"> 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();</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = 1; i <= 11; i++<span style="color: rgba(0, 0, 0, 1)">) { Connection conn </span>=<span style="color: rgba(0, 0, 0, 1)"> ds.getConnection(); System.out.println(conn); </span><span style="color: rgba(0, 0, 255, 1)">if</span> (i==5<span style="color: rgba(0, 0, 0, 1)">) { 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 方法,不过此时表示的是归还对象,并不是释放资源。
用完要及时归还。