本篇介绍几种开源数据库连接池,同时重点讲述如何使用C3P0数据库连接池。

  之前的博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式。这样能减少数据库创建连接的消耗。正是由于数据库连接池的思想非常重要,所以市面上也有很多开源的数据库连接池供我们使用。主要有以下三个:

  DBCP数据库连接池

  C3P0 数据库连接池

  Tomcat内置的数据库连接池(DBCP)

  本篇主要讲述C3P0数据库连接池的使用,关于另外两个数据库连接池的用法请看《开源数据库连接池之DBCP》 、《开源数据库连接池之Tomcat内置连接池》 。如果我们使用这些开源的数据库连接池,我们就可以省略像前一篇博客中自己创建数据库连接池的步骤,这样会省略我们很多事。

  C3P0的官网是http://sourceforge.net/projects/c3p0/?source=navbar ,比较不好找。

  C3P0实现了连接池和JNDI的绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0与DBCP的区别在于DBCP没有自动回收空闲连接的功能,而C3P0却有。但是C3P0在从连接池中获取和返回连接对象的时候,采用了异步处理方式(即非线程安全,关于异步可以看这篇很好的文章http://www.cnblogs.com/xiohao/p/4385508.html )。

  要想了解更多关于C3P0概念的信息,可以通过下载的C3P0的包中的【doc】目录下的index.html来查看关于C3P0的一些信息:

  

这里面有一些很有帮助的文档,例如快速入门(QuickStart)等等,这里就简单介绍一下:

  

要使用C3P0同样需要下载其jar包,在C3P0的jar包中共有三个jar包,如下图所示:

  

  如果使用的是非Oracle数据库,则只需导入c3p0-0.9.5.2jar包和mechange-commons-java-0.2.11.jar包即可,如果是使用Oracle数据库的话,还需要导入c3p0-oracle-thin-extras-0.9.5.2.jar包。

  C3P0可以有两种使用方法,一种是直接在程序中以调用ComboPooledDataSource对象的一系列方法配置各种数据库和连接池的参数,另一种也是跟DBCP一样使用配置文件来初始化数据库和连接池。

例1:使用第一种方式来简单创建C3P0数据库连接池

  在本例中我们仅使用C3P0的连接池类ComboPooledDataSource的对象来设置各个数据库驱动和连接池的参数,这种方法无需配置文件,换句话说也就是在程序中“写死”各个配置信息。

创建一个工程,因为我们使用的是MySQL数据库,因此只需要导入C3P0中的两个jar包即可,当然别忘了还有MySQL的数据库驱动jar包:

  

  同前一篇博客一样,我们现在是使用数据库连接池来获取连接了,而不是通过数据库直接提供的连接,因此《JDBC操作数据库的学习(2)》中的数据库工具类JdbcUtils的部分方法已经不适用了,现在我们重新在刚建的工程中编写一个新的JdbcUtils工具类:

 public class JdbcUtils {
private static ComboPooledDataSource ds = null;
static{
try {
ds = new ComboPooledDataSource();
ds.setDriverClass("com.mysql.jdbc.Driver"); //为C3P0配置MySQL数据库驱动
ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcdemo"); //为C3P0配置MySQL数据库URL
ds.setUser("root");
ds.setPassword("root");
ds.setMaxPoolSize(50); //设置连接池最大连接数
ds.setMinPoolSize(5); //设置连接池最小连接数
ds.setInitialPoolSize(10); //设置连接池初始化连接数 } catch (PropertyVetoException e) {
throw new ExceptionInInitializerError(e);
}
} public static Connection getConnection() throws SQLException {
return ds.getConnection(); //使用ComboPooledDataSource对象获取连接
} public static void release(Connection conn,Statement st,ResultSet rs) {
if(rs!=null) {
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(st!=null) {
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null) {
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}

  在上面的代码中,在该工具类一加载进内存时就利用C3P0的连接池类ComboPooledDataSource的对象来设置各个数据库驱动和连接池的参数,例如上面我们设置了数据库连接驱动、数据库URL、数据库用户名和密码、连接池里的最大和最小连接数,连接池初始化时的连接数等等,当然上面的配置只是ComboPooledDataSource对象中设置方法的冰山一角,我们还可以通过ComboPooledDataSource对象的方法为我们的连接池设置更多的功能和参数。

  而我们要给别的想操作数据库的方法返回的连接即使通过ComboPooledDataSource对象的getConnection()方法取得的Connection对象,另外通过释放资源的方法还是和以前一模一样,尤其是调用了Connection对象的close方法就能知道,这个Connection对象必定经过C3P0进行功能增强,将数据库直接提供的Connection对象的close方法进行了覆写,才能使我们释放资源时(调用Connection对象的close方法)不会将连接销毁,而是重新放入C3P0的连接池中。

  下面我们将通过一个测试代码来看看通过C3P0连接池获得的Connection对象:

 public void testConnection() throws SQLException {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null; try{
conn = JdbcUtils.getConnection();
System.out.println(conn);
System.out.println(conn.getClass().getName());
}finally{
JdbcUtils.release(conn, st, rs);
}
}

在控制台上显示的效果如下:

  

  红字信息是因为C3P0在创建数据库连接池时会通过日志来记录其工作的一些信息,我们也可以通过这个信息来查看C3P0创建的连接池的情况。

  最后两行是我们通过上面的测试代码打印出来的Connection对象的信息,可以看到C3P0也将数据库驱动直接提供的Connection对象进行了功能增强,而这种增强方式是通过动态代理方式来覆写了原来Connection对象的close方法再返回给我们的,以使我们在释放资源时能将连接重新返回到C3P0的连接池中。

例2:使用第二种方式来简单创建C3P0数据库连接池

  和第一种方式不同,在本例中我们使用配置文件的方式使C3P0能配置我们的数据库驱动和连接池所需要的参数。这种方式的好处就是不会在程序里将这些参数“写死”。

  C3P0的配置文件里使用什么参数关键字呢?配置文件有没特殊的命名方式呢?配置文件需要放置在什么特别的地方吗?这三个问题是使用C3P0连接池第二种方式必须要知道的。

  先说配置文件里使用的参数关键字,这个可以由ComboPooledDataSource对象中的各种set方法得到,比如这个对象中的setDriverClass方法,那么使用配置文件的话配置数据库驱动类的参数即为driverClass。另一种参看C3P0配置参数的方式就是看上面曾经说过的C3P0的包中【doc】目录下的index.html文档,在这个文档找到附录B(Appendix B:Configuration Files)有如下配置参数:

  

  在这张表的下面还有对每一个参数的各种介绍功能和一些默认值,这里就省略不贴图出来了。

  接下来就是配置文件了,和DBCP不一样,C3P0必须使用XML来作为配置文件,而且配置文件名和应该放置的位置都有严格的规定:

  

  首先C3P0的配置文件必须要叫“c3p0-config.xml”,另外根据文档,这个配置文件必须要直接或者以jar包的形式存放在你应用的CLASSPATH路径或者WEB-INF/classes路径(WEB工程)下才行。当然我们知道在MyEclipse上如果将配置文件放在【src】目录中在IED编译运行时会自动将【src】中的文件放置在CLASSPATH路径中,所以我们可以直接将配置文件放在【src】目录里。

  而文档也提供了一个配置文件中参数内容的例子:

<c3p0-config>
<default-config>
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property> <user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides> </default-config> <!-- This app is massive! -->
<named-config name="intergalactoApp">
<property name="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000</property> <!-- intergalactoApp adopts a different approach to configuring statement caching -->
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property> <!-- he's important, but there's only one of him -->
<user-overrides user="master-of-the-universe">
<property name="acquireIncrement">1</property>
<property name="initialPoolSize">1</property>
<property name="minPoolSize">1</property>
<property name="maxPoolSize">5</property>
<property name="maxStatementsPerConnection">50</property>
</user-overrides>
</named-config>
</c3p0-config>

  在官方给出的配置文件例子中,有默认配置和自定义配置两种:

  

  ⑴ 如果想用默认配置,则在程序中只要在创建ComboPooledDataSource对象时调用其无参的构造器即可,例如ComboPooledDataSource ds = new ComboPooledDataSource()即是使用默认配置。

  ⑵ 如果是想使用自定义配置,则在创建ComboPooledDataSource对象时将自定义配置的<named-config>指定的名称作为参数传进ComboPooledDataSource的构造器即可,例如按上图的例子来说ComboPooledDataSource ds = new ComboPooledDataSource(“intergalactoApp”)。因此这个配置文件可以配置多个自定义的参数内容,非常灵活,比如我们可以在一个C3P0配置文件中分别自定义MySQL数据库和Oracle数据库的配置参数。

  现在我们开始真正地使用第二种方式来使用C3P0连接池,创建一个工程,因为我们使用的是MySQL数据库,因此只需要导入C3P0中的两个jar包即可,当然别忘了还有MySQL的数据库驱动jar包:

  

  这回我们在【src】目录中放置C3P0的配置文件c3p0-config.xml,内容以文档案例做了修改如下:

<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcdemo</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">50</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config> <!-- if you want to use Oracle database -->
<named-config name="oracle">
<property name="driverClass">oracle.jdbc.driver.OracleDriver</property>
<property name="jdbcUrl"> jdbc:oracle:thin:@localhost:1521:jdbcdemo</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">50</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</named-config>
</c3p0-config>

  在这个配置文件中,默认配置是使用MySQL数据库,也设置了一个自定义配置可以使用Oracle数据库。

  同例1一样,我们也是要改写以前的数据库工具类JdbcUtils,代码如下:

 public class JdbcUtils {
private static ComboPooledDataSource ds = null;
static{
try {
ds = new ComboPooledDataSource(); //使用配置文件中的默认配置
// ds = new ComboPooledDataSource("oracle"); 如果要使用Oracle则使用配置文件中的自定义配置 } catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
} public static Connection getConnection() throws SQLException {
return ds.getConnection(); //使用ComboPooledDataSource对象获取连接
} public static void release(Connection conn,Statement st,ResultSet rs) {
if(rs!=null) {
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(st!=null) {
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null) {
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}

  在这个代码中,通过ComboPooledDataSource获取C3P0的连接池对象,因为我们在创建该对象时没有在构造器中传入参数,因此使用的是默认配置,而我们在配置文件中的默认设置也就是使用MySQL数据库。

  当然获取连接的getConnection方法和释放资源的release方法都还和例1 一样,通过连接池对象ComboPooledDataSource获取连接,而释放资源跟以前的代码没有任何区别,说明在释放资源调用Connection对象的close方法时,其实已经是被ComboPooledDataSource返回的另一种Connection对象覆写了close方法。

  我们通过下面的代码再来试下通过配置文件的方式使用C3P0的连接好不好使:

 public void testConnection() throws SQLException {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null; try{
conn = JdbcUtils.getConnection();
System.out.println(conn);
System.out.println(conn.getClass().getName());
}finally{
JdbcUtils.release(conn, st, rs);
}
}

  在控制台效果如下,我们照样从C3P0连接池中获取到了连接:

  

  以上就是我们对开源数据库连接池C3P0的整个学习和使用的过程。如果想对C3P0有更深入的理解,上面说过的文档可以是很好的学习方式。

参考博客:

http://weifly.iteye.com/blog/1227182

开源数据库连接池之C3P0的更多相关文章

  1. 开源数据库连接池之Tomcat内置连接池

    本篇介绍几种开源数据库连接池,同时重点讲述如何使用Tomcat服务器内置的数据库连接池. 之前的博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式.这样能减少数 ...

  2. 开源数据库连接池之DBCP

    本篇介绍几种开源数据库连接池,同时重点讲述如何使用Apache公司的的DBCP数据库连接池. 前面一篇博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式.这样能 ...

  3. 主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid)

    主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDB ...

  4. java攻城狮之路--复习JDBC(数据库连接池 : C3P0、DBCP)

    复习数据库连接池 : C3P0.DBCP 1.数据库连接池技术的优点: •资源重用:      由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销.在减少系统消耗的基础上,另一方面也增 ...

  5. JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 ...

  6. 【转】JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    转自:http://www.cnblogs.com/ysw-go/ JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/ ...

  7. 数据库连接池(c3p0)

    (一)问题的提出: 在使用开发基于数据库的web程序时,传统的数据库使用模式按照以下步骤: 在程序中建立数据库连接 进行sql操作 断开数据库连接 但是,这种模式存在着移动的问题: 传统连接模式每次向 ...

  8. java之数据库连接池-dbcp&c3p0&dbutils

    介绍 因为数据库连接对象的创建比较消耗性能,所以可以在应用程序启动时就在内存中开辟一片空间(集合)存放多个数据库连接对象,后面需要连接时直接从该空间中取而不用新创建:使用完毕后归还连接(将连接重新放回 ...

  9. [javaEE] 开源数据库连接池

    一些开源组织提供了数据源的独立实现: DBCP数据库连接池 C3P0数据库连接池 Apache Tomcat内置的连接池 DBCP连接池 apache提供的连接池实现,需要导入common-dbcp. ...

随机推荐

  1. 在 Windows Azure 网站 (WAWS) 上对 Orchard CMS 使用 Azure 缓存

    编辑人员注释: 本文章由 Windows Azure 网站团队的项目经理 Sunitha Muthukrishna 撰写. 如果您当前的 OrchardCMS 网站在 Windows Azure 网站 ...

  2. GDKOI2016

    天若有情天亦老 月若无恨月常圆 Day1 score cardcaptor AAAAAAAATT protal WWWWWWWWWW treasurehunt AAAAWXXXXX map AAATT ...

  3. Eclipse中设置tomcat的启动内存

    现象:眼下每次使用Eclipse启动Tomcat 的时候常常出现OutOfMemoryError thrown from the UncaughtExceptionHandler in thread ...

  4. postgres-xc手册生成方法

    步骤   检测编译环境  安装编译工具  编译 以上只在linux环境当中进行,本人所用系统ubuntu15.04 检测编译环境 在posgtgresql目录下运行./configure,并安装需要安 ...

  5. Xcode插件(一)-规范注释生成器VVDocumenter

    原文来自:http://blog.csdn.net/hitwhylz/article/details/27813315 分享几个常用的Xcode插件. 第一个, 规范注释生成器VVDocumenter ...

  6. 基于visual Studio2013解决算法导论之045斐波那契堆

     题目 斐波那契堆 解决代码及点评 // 斐波那契堆.cpp : 定义控制台应用程序的入口点. // #include<iostream> #include<cstdio> ...

  7. 第一次PS练习

    嘿嘿,自己第一次的PS,虽然把在大神眼里是小KS,但是了,对我来说值得劲纪念.加油,我会努力的.

  8. RVCT的Linux环境变量配置 ARM® RVDS™ 4.1(b713)

    下载解压 armrvds.tar.gz到/opt 下 在自己的build.sh下导入RVCT的环境变量配置ARM® RVDS™4.1(b713): export ARMROOT=/opt/armrvd ...

  9. scrapy新浪天气

    一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面上的程序: LX终端(LXTermin ...

  10. 基于visual Studio2013解决C语言竞赛题之0610冒泡排序函数

      题目