数据库连接池c3p0

一、概述:

数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,c3p0有两种数据源管理方式,一种是通过程序变本身来进行管理,还有一种是通过容器管理,本节讨论通过程序本身来进行管理,下一节讨论通过容器进行管理。

二、c3p0的三种实现方式

1、实现方式一:利用c3p0的API自己动手写代码,实现数据源

例如:在类路径下配置一个属性文件,config.properties,内容如下:

Java代码  

  1. driverClass=xxx
  2. jdbcUrl=xxx
  3. user=xxx
  4. password=xxx

相关的Java程序片段为:

Java代码  

  1. Properties props = new Properties();
  2. InputStream in = Thread.class.getResourceAsStream("config.properties");
  3. props.load(in);
  4. in.close();
  5. ComboPooledDataSource cpds = new ComboPooledDataSource();
  6. cpds.setDriverClass(props.getProperty("driverClass"));
  7. cpds.setJdbcUrl(props.getProperty("jdbcUrl"));
  8. cpds.setUser(props.getProperty("user"));
  9. cpds.setPassword(props.getProperty("password"));

这里只实现了一个数据源,也可以在类路径下配置一个xml文件,config.xml

Xml代码  

  1. <config>
  2. <source name="source1">
  3. <property name="user">root</property>
  4. <property name="password">xxx</property>
  5. <property name="url">xxx</property>
  6. <property name="driverClass">xxx</property>
  7. </source>
  8. <source name="source2">
  9. ...
  10. </source>
  11. </config>

然后自己解析xml文件,这样可以实现多个数据源的配置

2、实现方式二:类路径下提供一个c3p0.properties文件,文件名必须为c3p0.properties

配置如下:

Xml代码  

  1. #驱动
  2. c3p0.driverClass=com.mysql.jdbc.Driver
  3. #地址
  4. c3p0.jdbcUrl=jdbc:mysql://d-shc-00426378/tools
  5. #用户名
  6. c3p0.user=root
  7. #密码
  8. c3p0.password=root

这里只提供了最基本的配置项,其他配置项参照 文档配置,记得是c3p0.后面加属性名就是了,最后初始化数据源的方式就是这样简单:

Java代码  

  1. ...
  2. DataSource  ds = new ComboPooledDataSource();
  3. return ds;
  4. ...

然后就可以使用数据源了,C3P0会对c3p0.properties进行自动解析的。

3、实现方式二:类路径下提供一个c3p0-config.xml文件

这种方式与第二种差不多,但是有更多的优点 
(1).更直观明显,很类似hibernate和spring的配置
(2).可以为多个数据源服务,提供default-config和named-config两种配置方式

Xml代码  

  1. <c3p0-config>
  2. <default-config>
  3. <property name="user">root</property>
  4. <property name="password">java</property>
  5. <property name="driverClass">com.mysql.jdbc.Driver</property>
  6. <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
  7. <property name="initialPoolSize">10</property>
  8. <property name="maxIdleTime">30</property>
  9. <property name="maxPoolSize">100</property>
  10. <property name="minPoolSize">10</property>
  11. </default-config>
  12. <named-config name="mySource">
  13. <property name="user">root</property>
  14. <property name="password">java</property>
  15. <property name="driverClass">com.mysql.jdbc.Driver</property>
  16. <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
  17. <property name="initialPoolSize">10</property>
  18. <property name="maxIdleTime">30</property>
  19. <property name="maxPoolSize">100</property>
  20. <property name="minPoolSize">10</property>
  21. </named-config>
  22. </c3p0-config>

Java代码  

  1. ...
  2. DataSource  ds = new ComboPooledDataSource("mySource");
  3. return ds;
  4. ...

这样就可以使用数据源了。

三、实例,以第二种方式,即c3p0.propertis的方式为例说明

1、在classpath下创建一个文件,c3p0.properteis

Xml代码  

  1. #驱动
  2. c3p0.driverClass=com.mysql.jdbc.Driver
  3. #地址
  4. c3p0.jdbcUrl=jdbc:mysql://d-shc-00426378/tools
  5. #用户名
  6. c3p0.user=root
  7. #密码
  8. c3p0.password=root
  9. #-------------------------------
  10. #连接池初始化时创建的连接数
  11. c3p0.initialPoolSize=3
  12. #连接池保持的最小连接数
  13. c3p0.minPoolSize=3
  14. #连接池在无空闲连接可用时一次性创建的新数据库连接数,default:3
  15. c3p0.acquireIncrement=3
  16. #连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放,所以这个值有可能会设计地很大,default : 15
  17. c3p0.maxPoolSize=15
  18. #连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接,单位秒
  19. c3p0.maxIdleTime=100
  20. #连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功
  21. c3p0.acquireRetryAttempts=30
  22. #连接池在获得新连接时的间隔时间
  23. c3p0.acquireRetryDelay=1000

2、封装一个C3p0ConnectionPool用来创建数据库连接

Java代码  

  1. package com.wsheng.aggregator.c3p0;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import javax.sql.DataSource;
  5. import com.mchange.v2.c3p0.ComboPooledDataSource;
  6. /**
  7. * @author Josh Wang(Sheng)
  8. *
  9. * @email  [email protected]
  10. *
  11. */
  12. public class C3p0ConnectionPool {
  13. private DataSource ds;
  14. private static C3p0ConnectionPool pool;
  15. private C3p0ConnectionPool() {
  16. ds = new ComboPooledDataSource();
  17. }
  18. // 加上synchronized就是典型的同步模式
  19. public static /*synchronized*/ final C3p0ConnectionPool getInstance() {
  20. if (pool == null) {
  21. try {
  22. pool = new C3p0ConnectionPool();
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. return pool;
  28. }
  29. // synchronized保证每个pool线程请求返回的都是不同的Connection
  30. public synchronized final Connection getConnection() {
  31. try {
  32. Connection connection = ds.getConnection();
  33. // 1)将配置文件中的c3p0.initialPoolSize,c3p0.minPoolSize,c3p0.maxPoolSize都改为1,然后执行查看结果
  34. // 2)将配置文件中的c3p0.initialPoolSize,c3p0.minPoolSize,c3p0.maxPoolSize都改为较小的值,加大线程数,然后执行查看结果
  35. System.out.println(" **** current connection number: " + ((ComboPooledDataSource)ds).getNumConnections()
  36. + " busy connection number: " + ((ComboPooledDataSource)ds).getNumBusyConnections()
  37. + " Idle connection nmuber: " + ((ComboPooledDataSource)ds).getNumIdleConnections());
  38. return connection;
  39. } catch (SQLException e) {
  40. e.printStackTrace();
  41. }
  42. return null;
  43. }
  44. }

3、创建模拟用户发起数据库连接的Thread类

Java代码  

  1. package com.wsheng.aggregator.c3p0;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. /**
  6. * @author Josh Wang(Sheng)
  7. *
  8. * @email [email protected]
  9. *
  10. */
  11. public class C3p0PoolThread extends Thread {
  12. @Override
  13. public void run() {
  14. C3p0ConnectionPool pool = C3p0ConnectionPool.getInstance();
  15. Connection connection = null;
  16. PreparedStatement stmt = null;
  17. ResultSet rs = null;
  18. try {
  19. connection = pool.getConnection();
  20. stmt = connection.prepareStatement("select sysdate() as nowtime from dual");
  21. rs = stmt.executeQuery();
  22. while (rs.next()) {
  23. System.out.println(Thread.currentThread().getId() + "---------------开始" + rs.getString("nowtime"));
  24. }
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. } finally {
  28. try {
  29. rs.close();
  30. stmt.close();
  31. connection.close();
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. System.out.println(Thread.currentThread().getId() + "--------结束");
  37. }
  38. }

4、Main类

Java代码  

  1. package com.wsheng.aggregator.c3p0;
  2. /**
  3. * @author Josh Wang(Sheng)
  4. *
  5. * @email  [email protected]
  6. *
  7. */
  8. public class C3p0Main {
  9. public static void main(String[] args) {
  10. System.out.println("数据库连接池模拟开始");
  11. C3p0PoolThread[] threads = new C3p0PoolThread[100];
  12. for (int i = 0; i < threads.length;i++) {
  13. threads[i] = new C3p0PoolThread();
  14. }
  15. for (int i= 0;i < threads.length; i++) {
  16. threads[i].start();
  17. }
  18. }
  19. }

 在C3p0Main.java中可以增加线程数,也可以再c3p0.properties中减少c3p0.maxPoolSize, c3p0.minPoolSize, c3p0.initialPoolSize等的值来查看执行结果。

四、常用配置参数的说明:

1.最常用配置

initialPoolSize: 连接池初始化时创建的连接数,default : 3(建议使用)

minPoolSize: 连接池保持的最小连接数,default : 3(建议使用)

maxPoolSize: 连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放,所以这个值有可能会设计地很大,default : 15(建议使用)

acquireIncrement:连接池在无空闲连接可用时一次性创建的新数据库连接数,default : 3(建议使用)

2.管理连接池的大小和连接的生存时间

maxConnectionAge:配置连接的生存时间,超过这个时间的连接将由连接池自动断开丢弃掉。当然正在使用的连接不会马上断开,而是等待它close再断开。配置为0的时候则不会对连接的生存时间进行限制。default : 0 单位 s(不建议使用)

maxIdleTime:连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接。如果为0,则永远不会断开连接,即回收此连接。default : 0 单位 s(建议使用)

maxIdleTimeExcessConnections:这个配置主要是为了快速减轻连接池的负载,比如连接池中连接数因为某次数据访问高峰导致创建了很多数据连接,但是后面的时间段需要的数据库连接数很少,需要快速释放,必须小于maxIdleTime。其实这个没必要配置,maxIdleTime已经配置了。default : 0 单位 s(不建议使用)

3.配置连接测试:

automaticTestTable:配置一个表名,连接池根据这个表名用自己的测试sql语句在这个空表上测试数据库连接,这个表只能由c3p0来使用,用户不能操作。default : null(不建议使用)

preferredTestQuery:与上面的automaticTestTable二者只能选一。自己实现一条SQL检测语句。default : null(建议使用)

idleConnectionTestPeriod:用来配置测试空闲连接的间隔时间。测试方式还是上面的两种之一,可以用来解决MySQL8小时断开连接的问题。因为它保证连接池会每隔一定时间对空闲连接进行一次测试,从而保证有效的空闲连接能每隔一定时间访问一次数据库,将于MySQL8小时无会话的状态打破。为0则不测试。default : 0(建议使用)

testConnectionOnCheckin:如果为true,则在close的时候测试连接的有效性。default : false(不建议使用)

testConnectionOnCheckout:性能消耗大。如果为true,在每次getConnection的时候都会测试,为了提高性能,尽量不要用。default : false(不建议使用)

4.配置PreparedStatement缓存:

maxStatements:连接池为数据源缓存的PreparedStatement的总数。由于PreparedStatement属于单个Connection,所以这个数量应该根据应用中平均连接数乘以每个连接的平均PreparedStatement来计算。同时maxStatementsPerConnection的配置无效。default : 0(不建议使用)

maxStatementsPerConnection:连接池为数据源单个Connection缓存的PreparedStatement数,这个配置比maxStatements更有意义,因为它缓存的服务对象是单个数据连接,如果设置的好,肯定是可以提高性能的。为0的时候不缓存。default : 0(看情况而论)

5.重连相关配置 

acquireRetryAttempts:连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功。default : 30(建议使用)

acquireRetryDelay:连接池在获得新连接时的间隔时间。default : 1000 单位ms(建议使用)

breakAfterAcquireFailure:如果为true,则当连接获取失败时自动关闭数据源,除非重新启动应用程序。所以一般不用。default : false(不建议使用)

checkoutTimeout:配置当连接池所有连接用完时应用程序getConnection的等待时间。为0则无限等待直至有其他连接释放或者创建新的连接,不为0则当时间到的时候如果仍没有获得连接,则会抛出SQLException。其实就是acquireRetryAttempts*acquireRetryDelay。default : 0(与上面两个,有重复,选择其中两个都行)

6.定制管理Connection的生命周期

connectionCustomizerClassName:用来定制Connection的管理,比如在Connection acquire 的时候设定Connection的隔离级别,或者在Connection丢弃的时候进行资源关闭,

就可以通过继承一个AbstractConnectionCustomizer来实现相关方法,配置的时候使用全类名。有点类似监听器的作用。default : null(不建议使用)

7.配置未提交的事务处理 

autoCommitOnClose:连接池在回收数据库连接时是否自动提交事务。如果为false,则会回滚未提交的事务,如果为true,则会自动提交事务。default : false(不建议使用)

forceIgnoreUnresolvedTransactions:这个配置强烈不建议为true。default : false(不建议使用)

一般来说事务当然由自己关闭了,为什么要让连接池来处理这种不细心问题呢?

8.配置debug和回收Connection

unreturnedConnectionTimeout:为0的时候要求所有的Connection在应用程序中必须关闭。如果不为0,则强制在设定的时间到达后回收Connection,所以必须小心设置,保证在回收之前所有数据库操作都能够完成。这种限制减少Connection未关闭情况的不是很适用。建议手动关闭。default : 0 单位 s(不建议使用)

debugUnreturnedConnectionStackTraces:如果为true并且unreturnedConnectionTimeout设为大于0的值,当所有被getConnection出去的连接unreturnedConnectionTimeout时间到的时候,就会打印出堆栈信息。只能在debug模式下适用,因为打印堆栈信息会减慢getConnection的速度default : false(不建议使用)

其他配置项:因为有些配置项几乎没有自己配置的必要,使用默认值就好,所以没有再写出来。

时间: 2024-12-25 23:13:05

数据库连接池c3p0的相关文章

数据库连接JDBC和数据库连接池C3P0自定义的java封装类

数据库连接JDBC和数据库连接池C3P0自定义的java封装类 使用以下的包装类都需要自己有JDBC的驱动jar包: 如 mysql-connector-java-5.1.26-bin.jar(5.1.26代表的是版本序列号) 一.JDBC的封装:(java连接MySQL) 1 import java.sql.*; 2 3 import utils.GlobalConstant; 4 5 public class JDBCUtil { 6 7 private JDBCUtil() { 8 9 }

数据库连接池C3P0学习

数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,这里只讨论程序本身负责数据源,不讨论容器管理. 一.实现方式: C3P0有三种方式实现: 1.自己动手写代码,实现数据源 例如:在类路径下配置一个属性文件,config.properties,内容如下: driverClass=xxx jdbcUrl=xxx user=xxx password=xxx ... 然后代码中实现 Properties props = new Properties(); InputStream i

Spring数据库连接池 c3p0、dbcp、spring-jdbc

在用dbcp的时候 后面加上 destroy-method="close" 销毁的方法没事 但是用 spring的jdbc就会报错 提示找不到close这个方法  这是为什么? DBCP DBCP(DataBase connection pool),数据库连接池.是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件.单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为

数据库连接池--C3P0实现

1.C3P0 简介 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等. C3P0的数据库连接池的核心类是ComboPooledDataSource 使用C3P0需要在工程中导入的jar包 c3p0-0.9.2-pre5\lib下有三个jar包,如果使用MySQL数据库,只需导入c3p0-0.9.2-pre5.jar,mchange-commons-java-0.2.3两个包即可,另

通过实现ServletContextListener接口创建数据库连接池(C3P0方式)

使用Listener步骤 1. 定义Listener实现类 2. 在web.xml中配置(或使用Annotation) 使用C3P0方式创建数据库连接池需要添加的jar包 1.c3p0-0.9.5.jar 2.c3p0-oracle-thin-extras-0.9.5.jar 3.mchange-commons-java-0.2.9.jar 1 package cn.sdut.lah.listener; 2 3 import java.sql.Connection; 4 import javax

记性不如烂笔头22-JAVA数据库连接池 C3P0

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等.C3P0数据源在项目开发中使用得比较多. 1.c3p0与dbcp区别 dbcp没有自动回收空闲连接的功能 c3p0有自动回收空闲连接功能 c3p0支持更加多的数据库连接池选项. 2.导入相关jar包 c3p0-0.9.0.jar 3.C3P0参数详解 datasource.c3p0.acquireIncrement=10当连接池中的

[数据库连接池二]Java数据库连接池--C3P0和JDNI.

前言:上一篇文章中讲了DBCP的用法以及实现原理, 这一篇再来说下C3P0和JDNI的用法. 1.1.C3P0数据源 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等.C3P0数据源在项目开发中使用得比较多. c3p0与dbcp区别 dbcp没有自动回收空闲连接的功能 c3p0有自动回收空闲连接功能 1.2.在应用程序中加入C3P0连接池 1.导入相关jar包    c3p0-0.

数据库连接池c3p0和dbcp

转载:http://www.cnblogs.com/haogeBlogs/p/5856302.html 现在常用的开源数据连接池主要有c3p0.dbcp和proxool三种,其中: hibernate开发组推荐使用c3p0; spring开发组推荐使用dbcp(dbcp连接池有weblogic连接池同样的问题,就是强行关闭连接或数据库重启后,无法reconnect,告诉连接被重置,这个设置可以解决); hibernate in action推荐使用c3p0和proxool; dbcp所需jar:

数据库连接池——C3P0

定义: 本质上就是个容器(集合)存放数据库连接的容器.当系统初始化以后,容器被创建,容器中就会申请一些连接对象.当用户来访问的数据库的时候,从容器中取连接对象,用户用完之后归还. 使用方法: 标准接口为javax.sql包下的Datasource.(一般不实现该接口,数据库厂商或者连接池厂商来实现这个接口) 获得连接:getConnection(); 归还连接对象给连接池:Connection.close(): 使用步骤: 1  导包 两个包 c3p0-0.9.5.2.jar和mchange-c