整理网上关于数据库连接池的文章

1、数据库连接池汇总

C3P0

C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

Proxool

这是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能。

Jakarta DBCP

DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序用使用。

DDConnectionBroker

DDConnectionBroker是一个简单,轻量级的数据库连接池。

DBPool

DBPool是一个高效的易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池使你能够开发一个满足自已需求的数据库连接池。

XAPool

XAPool是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。

Primrose

Primrose是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5,Resin3与JBoss3.它同样也有一个独立的版本可以在应用程序中使用而不必运行在容器中。Primrose通过一个web接口来控制SQL处理的追踪,配置,动态池管理。在重负荷的情况下可进行连接请求队列处理。

SmartPool

SmartPool是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks),连接阻塞,打开的JDBC对象如Statements,PreparedStatements等. SmartPool的特性包括支持多个pools,自动关闭相关联的JDBC对象, 在所设定time-outs之后察觉连接泄漏,追踪连接使用情况, 强制启用最近最少用到的连接,把SmartPool"包装"成现存的一个pool等。

MiniConnectionPoolManager

MiniConnectionPoolManager是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。

BoneCP

BoneCP是一个快速,开源的数据库连接池。帮你管理数据连接让你的应用程序能更快速地访问数据库。比C3P0/DBCP连接池快25倍。

Druid

Druid是一个JDBC组件,它包括三部分:
  • DruidDriver代理Driver,能够提供基于Filter-Chain模式的插件体系。
  • DruidDataSource高效可管理的数据库连接池。
  • SQLParser

  • 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
  • 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
  • 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
  • SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
  • 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。如下是一个基于Druid内置扩展StatFilter的监控实现:
    Druidn.jpg
    收录时间:2011-05-11 21:39:47


  • 2、数据库连接池的配置

    1,直接连接数据库的情形: ,直接连接数据库的情形:
    public class DBUtil { 
    
    /** * 单例模式创建数据库对象 */ 
    
    private static DBUtil instance=null;
    
    private DBUtil(){} //为了保证单例性,必须使用同步关键字 
    
    public synchronized static DBUtil getInstance(){
    
     if(instance==null) instance=new DBUtil();
    
      return instance;
    
     } //连接必要的信息
    
     public String driver="com.mysql.jdbc.Driver";
    
     public String url="jdbc:mysql://localhost:3306/test";
    
     public String username="root";
    
     public String password="8921498YW";
    
     public Connection getConnection(){
    
      Connection conn=null;
    
      try {
    
      Class.forName(driver);
    
       conn=DriverManager.getConnection(url, username, password);
    
      } catch (ClassNotFoundException e) {
    
       e.printStackTrace();
    
      } catch (SQLException e) {
    
       e.printStackTrace();
    
      }
    
     return conn;
    
     } //测试连接的效率
    
     public static void main(String[] args) throws SQLException {
    
      long begin=System.currentTimeMillis();//开始时刻
    
      for(int i=0;i<1000;i++){//获得1000次连接
    
       Connection conn=DBUtil.getInstance().getConnection();
    
       conn.close();
    
      }
    
      long end=System.currentTimeMillis();
    
      System.out.println("直接连接数据库所需要的时 间:"+(end-begin)); //在我的机子上1000次直接连接耗时:12031
    
     }
    
     } 
    
    2, 使用 DBCP 连接池: , 连接池: /** * 数据库连接池 : * 它是程序启动时建立足够的数据库连接,并将这些连接组成一个连 接池,由程序动态的对池中的连接进行申请,使用,释放 * * DBCP是apache组织下的一个开源项目 * 需要两个jar包,commons-dbcp-1.2.2和commons-pool * 这种连接池效率很高,但经常出现连接丢失现象,用的不是很多, 用的多的是c3p0 * */
    public class DBUtilOfDBCP { 
    
    private static BasicDataSource dataSource=null;// 数据源
    
     private static DataSourceConnectionFactory factory;//连接工厂 
    
    private static DBUtilOfDBCP instance=null; private DBUtilOfDBCP(){ 
    
    dataSource=new BasicDataSource(); //设置jdbc相关信息
    
     dataSource.setUrl(url);
    
     dataSource.setUsername(username);
    
     dataSource.setPassword(password);
    
     dataSource.setDriverClassName(driver); //连接池设置
    
     dataSource.setInitialSize(20);//初始连接数
    
     dataSource.setMaxActive(100);//最大获取连接数
    
     dataSource.setMaxIdle(30);//最大可用空闲连接数
    
     dataSource.setMinIdle(10);//最小可用空闲连接数
    
     factory=new DataSourceConnectionFactory(dataSource); 
    
    } //为了保证单例性,必须使用同步关键字
    
     public synchronized static DBUtilOfDBCP getInstance(){
    
     if(instance==null) instance=new DBUtilOfDBCP();
    
     return instance; 
    
    } //连接必要的信息
    
     public String driver="com.mysql.jdbc.Driver";
    
     public String url="jdbc:mysql://localhost:3306/test";
    
     public String username="root";
    
     public String password="8921498YW";
    
     public Connection getConnection() throws SQLException{ //使用工厂创建连接 return factory.createConnection();
    
     }
    
     public static void main(String[] args) throws SQLException {
    
     long begin=System.currentTimeMillis();//开始时刻
    
     for(int i=0;i<1000;i++){//获得1000次连接
    
     Connection conn=DBUtilOfDBCP.getInstance().getConnection();
    
     conn.close(); 
    
    } 
    
    long end=System.currentTimeMillis();
    
     System.out.println("DBCP连接数据库所需要的时 间:"+(end-begin)); //在我的机子上1000次DBCP连接耗时:1000毫秒
    
     } 
    
    } 
    
    3,使用 C3P0 连接池: , 连接池: * C3P0,比较稳定 * 需要jar包:c3p0-0.9.1
    public class DBUtilOfC3P0 {
    
     private static ComboPooledDataSource dataSource; 
    
    private static DBUtilOfC3P0 instance=null; 
    
    private DBUtilOfC3P0(){ dataSource=new ComboPooledDataSource(); //设置jdbc连接信息 
    
    dataSource.setUser(username);
    
     dataSource.setPassword(password);
    
     dataSource.setJdbcUrl(url); 
    
    try { dataSource.setDriverClass(driver);
    
     } catch (PropertyVetoException e) {
    
     e.printStackTrace(); 
    
    } //设置连接池
    
     dataSource.setInitialPoolSize(30); 
    
    dataSource.setMaxPoolSize(100);
    
     dataSource.setMinPoolSize(10); } //为了保证单例性,必须使用同步关键字
    
     public synchronized static DBUtilOfC3P0 getInstance(){
    
     if(instance==null) instance=new DBUtilOfC3P0();
    
     return instance;
    
     } //连接必要的信息 
    
    public String driver="com.mysql.jdbc.Driver"; 
    
    public String url="jdbc:mysql://localhost:3306/test"; 
    
    public String username="root";
    
     public String password="8921498YW"; 
    
    public Connection getConnection() throws SQLException{ //使用工厂创建连接
    
     return dataSource.getConnection();
    
     } 
    
    public static void main(String[] args) throws SQLException {
    
     long begin=System.currentTimeMillis();
    
    //开始时刻 for(int i=0;i<1000;i++){//获得1000次连接
    
     Connection conn=DBUtilOfC3P0.getInstance().getConnection(); conn.close(); 
    
    } 
    
    long end=System.currentTimeMillis(); 
    
    System.out.println("C3P0连接数据库所需要的时 间:"+(end-begin)); //在我的机子上1000次C3P0连接耗时:1813毫秒
    
     } 
    
    } 
    

    3、数据连接池用法(boncp,dbcp,proxool,C3PO)

    C3PO数据库连接池

    优点:性能比较dbcp好,稳定性也比dbcp强

    将C3po跟spring整合

    1.导入c3p0-0.9.1.2.jar,commons-logging-1.1.1.jar,spring-2.5.6.jar

    2.在applicationContext.xml中配置,用C3PO配置好的数据源

    <bean

    id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass">
    <value>net.sourceforge.jtds.jdbc.Driver</value>
    </property>
    <property name="jdbcUrl">

    <value>jdbc:jtds:sqlserver://localhost:1433/hua</value>
    </property>
    <property name="user">
    <value>sa</value>
    </property>
    <property name="password">
    <value>hua</value>
    </property>
    <property name="minPoolSize">
    <value>15</value>
    </property>
    <property name="acquireIncrement">
    <value>5</value>
    </property>
    <property name="maxPoolSize">
    <value>25</value>
    </property>
    </bean>

    3.在dao类中就可以通过

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource ds=(DataSource)context.getBean("dataSource");

    Connection conn=ds.getConnection();

    Statement stmt=conn.creatStatement();

    ResultSet rs=stmt.executeQuery(sql);

    接着介绍一下C3PO的参数

    <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->

    <property name="acquireIncrement">3</property>

    <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->

    <property name="acquireRetryAttempts">30</property>

    <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->

    <property name="acquireRetryDelay">1000</property>

    <!--连接关闭时默认将所有未提交的操作回滚。Default: false -->

    <property name="autoCommitOnClose">false</property>

    <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么

    属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试

    使用。Default: null-->

    <property name="automaticTestTable">Test</property>

    <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效

    保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试

    获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->

    <property name="breakAfterAcquireFailure">false</property>

    <!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出

    SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->

    <property name="checkoutTimeout">100</property>

    <!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。

    Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->

    <property name="connectionTesterClassName"></property>

    <!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可

    Default: null-->

    <property name="factoryClassLocation">null</property>

    <!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.

    (文档原文)作者强烈建议不使用的一个属性-->

    <property name="forceIgnoreUnresolvedTransactions">false</property>

    <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->

    <property name="idleConnectionTestPeriod">60</property>

    <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->

    <property name="initialPoolSize">3</property>

    <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

    <property name="maxIdleTime">60</property>

    <!--连接池中保留的最大连接数。Default: 15 -->

    <property name="maxPoolSize">15</property>

    <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements

    属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。

    如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->

    <property name="maxStatements">100</property>

    <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->

    <property name="maxStatementsPerConnection"></property>

    <!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能

    通过多线程实现多个操作同时被执行。Default: 3-->

    <property name="numHelperThreads">3</property>

    <!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0

    的数据源时。Default: null-->

    <property name="overrideDefaultUser">root</property>

    <!--与overrideDefaultUser参数对应使用的一个参数。Default: null-->

    <property name="overrideDefaultPassword">password</property>

    <!--密码。Default: null-->

    <property name="password"></property>

    <!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:

    测试的表必须在初始数据源的时候就存在。Default: null-->

    <property name="preferredTestQuery">select id from test where id=1</property>

    <!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->

    <property name="propertyCycle">300</property>

    <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的

    时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable

    等方法来提升连接测试的性能。Default: false -->

    <property name="testConnectionOnCheckout">false</property>

    <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->

    <property name="testConnectionOnCheckin">true</property>

    <!--用户名。Default: null-->

    <property name="user">root</property>

    <!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数

    允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始

    广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到

    支持,但今后可能的版本可能不支持动态反射代理。Default: false-->

    DBCP数据连接池

    1.导入commons-dbcp.jar,commons-logging-1.1.1.jar,commons-pool.jar,spring-2.5.6.jar

    2.在applicationContext.xml中配置数据源

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

    <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value>

    </property>

    <property name="url"> <value>jdbc:mysql://localhost:3306/dbname?useUnicode=true&amp;characterEncoding=utf8</value>

    </property>

    <property name="username"> <value>root</value> </property>

    <property name="password"> <value>root</value> </property>

    <property name="initialSize"> <value>3</value> </property>

    <property name="maxActive"> <value>100</value> </property>

    <property name="maxIdle"> <value>5</value> </property>

    <property name="maxWait"> <value>10</value> </property>

    </bean>

    3.跟上面一样获取数据源

    4.参数介绍

    Ø BasicDataSource 相关的参数说明
    dataSource: 要连接的 datasource (通常我们不会定义在 server.xml)
    defaultAutoCommit: 对于事务是否 autoCommit, 默认值为 true
    defaultReadOnly: 对于数据库是否只能读取, 默认值为 false
    driverClassName:连接数据库所用的 JDBC Driver Class,
    maxActive: 可以从对象池中取出的对象最大个数,为0则表示没有限制,默认为8
    maxIdle: 最大等待连接中的数量,设 0 为没有限制 (对象池中对象最大个数)
    minIdle:对象池中对象最小个数
    maxWait: 最大等待秒数, 单位为 ms, 超过时间会丟出错误信息
    password: 登陆数据库所用的密码
    url: 连接数据库的 URL
    username: 登陆数据库所用的帐号
    validationQuery: 验证连接是否成功, SQL SELECT 指令至少要返回一行
    removeAbandoned: 是否自我中断, 默认是 false
    removeAbandonedTimeout: 几秒后会自我中断, removeAbandoned 必须为 true
    logAbandoned: 是否记录中断事件, 默认为 false
    minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证;默认30分钟
    timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程,默认-1
    testOnBorrow:取得对象时是否进行验证,检查对象是否有效,默认为false
    testOnReturn:返回对象时是否进行验证,检查对象是否有效,默认为false
    testWhileIdle:空闲时是否进行验证,检查对象是否有效,默认为false
    Ø 在使用DBCP的时候,如果使用默认值,则数据库连接因为某种原因断掉后,再从连接池中取得连接又不进行验证,这时取得的连接实际上就会是无效的数据库连接。因此为了防止获得的数据库连接失效,在使用的时候最好保证:
    username: 登陆数据库所用的帐号
    validationQuery:SELECT COUNT(*) FROM DUAL
    testOnBorrow、testOnReturn、testWhileIdle:最好都设为true
    minEvictableIdleTimeMillis:大于0 ,进行连接空闲时间判断,或为0,对空闲的连接不进行验证
    timeBetweenEvictionRunsMillis:失效检查线程运行时间间隔,如果小于等于0,不会启动检查线程
    Ø PS:在构造GenericObjectPool [BasicDataSource在其createDataSource () 方法中也会使用GenericObjectPool] 时,会生成一个内嵌类Evictor,实现自Runnable接口。如果timeBetweenEvictionRunsMillis大于0,每过timeBetweenEvictionRunsMillis毫秒Evictor会调用evict()方法,检查对象的闲置时间是否大于 minEvictableIdleTimeMillis毫秒(_minEvictableIdleTimeMillis小于等于0时则忽略,默认为30分钟),是则销毁此对象,否则就激活并校验对象,然后调用ensureMinIdle方法检查确保池中对象个数不小于_minIdle。在调用returnObject方法把对象放回对象池,首先检查该对象是否有效,然后调用PoolableObjectFactory 的passivateObject方法使对象处于非活动状态。再检查对象池中对象个数是否小于maxIdle,是则可以把此对象放回对象池,否则销毁此对象

    上面两个是基于Apache的开源连接池框架,如果你用的服务器也是Apache的,如:tomcat。建议使用

    bonecp数据连接池

    1.导入bonecp-0.7.0.jar,commons-logging-1.1.1.jar,google-collections-1.0.jar,log4j-1.2.15.jar,slf4j-api-1.6.0.jar,slf4j-log4j12-1.6.0.jar,spring-2.5.6.jar

    2.在applicationContext.xml中配置数据源

    <bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> 
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1/yourdb" />
    <property name="username" value="root"/> 
    <property name="password" value="abcdefgh"/> 
    <property name="idleConnectionTestPeriod" value="60"/> 
    <property name="idleMaxAge" value="240"/> 
    <property name="maxConnectionsPerPartition" value="30"/> 
    <property name="minConnectionsPerPartition" value="10"/> 
    <property name="partitionCount" value="3"/> 
    <property name="acquireIncrement" value="5"/> 
    <property name="statementsCacheSize" value="100"/> 
    <property name="releaseHelperThreads" value="3"/>
    </bean> 

    3.跟上面一样获取数据源

    4.

    BoneCP最大的特点就是效率,BoneCP号称是目前市面上最快的Java连接池,从官方的评测来看其效率远远超越了其它同类的Java连 接池产品

    • 高度可扩展, 快速的连接池.
    • 注:1)不用synchronized 关键字来处理多线程对资源的争用,而是使用 java.util.concurrent 包中的锁机制;
    • 2)首次使用分区机制来分开管理数据库连接;或许还有其他原因。
    • Callback (hook interceptor) mechanisms on a change of connection state.
    • 利用分区技术提高性能>
    • 允许直接访问一个连接或者语句
    • 智能调整连接池大小
    • SQL语句缓存支持
    • 支持异步获取数据库连接 (通过返回Future<Connection>的形式
    • 通过释放连接助理进程来释放数据库连接,提高性能.
    • 通过initSQL参数在每次获取连接的时候执行SQL
    • 支持数据库热切换
    • 自动重试失败的数据库操作(当数据库或者网络挂掉的时候)
    • JMX support
    • 延迟初始化能力(Lazy initialization capable)
    • 自动检测连接可用性 (keep-alives 等)
    • 允许直接通过数据源而不是通过驱动来获取一个新的数据库连接(Allow obtaining of new connections via a datasource rather than via a Driver)
    • Datasource/Hibernate support capable
    • Debug支持准确地高亮那些已经得到但是还没有关闭的链接(Debugging hooks to highlight the exact place where a connection was obtained but not closed)
    • Debug支持展示那些被关闭两次的链接地址堆栈信息(Debugging support to show stack locations of connections that were closed twice. )
    • 支持自定义连接池名称.
    • 干净的代码结构,TestCase代码覆盖率达到100% (over 125 JUnit tests).
    • 免费的,开源的而且都是用java干的,最重要的是有很完整的javadocs支持。(Free, open source and written in 100% pure Java with complete Javadocs).
    • 性能测试报告 可以看看这个http://www.oschina.net/p/bonecp

    Proxool数据连接池

    1.导入commons-logging.jar,proxool-0.9.0RC3.jar,spring-2.5.6.jar

    2.在Spring的"applicationContext.xml"中的dataSource bean定义——

    <beanid="dataSource"
    class
    ="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <propertyname="driverClassName">
    <value>org.logicalcobwebs.proxool.ProxoolDriver</value>
    </property>
    <propertyname="url">
    <value>proxool.Pool_dbname</value>
    </property>
    </bean>

    3.在"web.xml"先配置好Proxool连接池

    <servlet>
    <servlet-name>proxoolServletConfigurator</servlet-name>
    <servlet-class>
    org.logicalcobwebs.proxool.configuration.ServletConfigurator
    </servlet-class>
    <init-param>
    <param-name>xmlFile</param-name>
    <param-value>WEB-INF/proxool.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>
    4.写一个proxool.xml

    <?xmlversion="1.0"encoding="UTF-8"?>
    <proxool-config>
    <proxool>
    <alias>Pool_dbname</alias>
    <driver-url>jdbc:mysql://localhost:3306/dbname</driver-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <driver-properties>
    <propertyname="user"value="yourname"/>
    <propertyname="password"value="yourpass"/>
    </driver-properties>
    <house-keeping-sleep-time>60000</house-keeping-sleep-time>
    <maximum-connection-count>20</maximum-connection-count> 
    <minimum-connection-count>2</minimum-connection-count>
    <prototype-count>0</prototype-count>
    <simultaneous-build-throttle>20</simultaneous-build-throttle>
    <house-keeping-test-sql>selectCURRENT_DATE</house-keeping-test-sql>
    <statistics>15s,10m,1d</statistics>
    <statistics-log-level>INFO</statistics-log-level>
    </proxool>
    <proxool>
    <!--可以配置多个库-->
    </proxool>
    </proxool-config>

    5.最后跟上面一获取数据源

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource ds=(DataSource)context.getBean("dataSource");

    Connection conn=ds.getConnection();

    Statement stmt=conn.creatStatement();

    ResultSet rs=stmt.executeQuery(sql);

    6.参数介绍

    #alias是别名;
    #driver-url
    是驱动的url,就是连接的url
    #driver-class
    是驱动的类,就是数据库驱动;
    #user
    password是设置登陆数据库的用户名和密码
    #prototype-count
    最少保持的空闲连接数
    #maximum-connection-lifetime
    最大连接生命周期 默认值:4小时
    #maximum-active-time
    : 最大活动时间 默认值:5分钟
    #maximum-connection-count
    最大连接数 默认值:15
    #minimum-connection-count
    最小连接数 默认值:5
    #house-keeping-sleep-time proxool
    自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁
    #maximum-new-connections
    指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受

    4、Hibernate3已经不再支持DBCP连接池,而推荐使用C3PO

    DBCP的bug非常多,因此Hibernate3已经不再支持DBCP连接池,而推荐使用C3PO。建议你更换数据库连接池。


    然后跑去Hibernate官方论坛看,果然,在Please migrate away
    from DBCP看到Gavin说:
    引用:
    Guys, after many problems with DBCP, I have decided to remove built-in
    support for DBCP from Hibernate3, and deprecate DBCP in Hibernate 2.1.
    I advise everyone to migrate away from DBCP to something that actually
    works, like C3P0 or Proxool.


    (If you /must/ use DBCP, you can always write your own connection
    provider.)


    Actually, it is probably about time we remove any remaining
    dependencies to Apache commons stuff, since historically they have
    caused just /so/ much trouble. The only Apache things that do seem to
    work very well are Ant and log4j. Even commons-logging is a PIA,
    especially in Tomcat.

    C3P0是Hibernate3.0默认的自带数据库连接池,DBCP是Apache开发的数据库连接池。我们对这两种连接池进行压力测试对比,发现在并发30 0个用户以下时,DBCP比C3P0平均时间快1秒左右。但在并发400个用户时,两者差不多。


    速度上虽然DBCP比C3P0快些,但是有BUG:当DBCP建立的数据库连接,因为某种原因断掉后,DBCP将不会再重新创建新的连接,导致必须重新启动To mcat才能解决问题。DBCP的BUG使我们决定采用C3P0作为数据库连接池。

    ///////////////////////////////////////////////////////////////////////////////////////////

    hibernate3已經不支持直接配置dbcp了,因為dbcp的bugs太多了...
    為什麼網上的人老是這樣問怎麼配置dbcp.
    hibernate的reference已經說得很清楚了.
    實現org.hibernate.connection.ConnectionProvider接口就行了..
    package app.db;
    import org.apache.commons.dbcp.DataSourceConnectionFactory;
    public class DbcpDataSource {
    private static DataSource ds = null;
    private static ConnectionFactory factory = null;

    public static DataSource getDataSource() {
    return ds;
    }
    public static ConnectionFactory getConnectionFactory() {
    return factory;
    }
    public static int getNumActive() {
    return ((BasicDataSource) ds).getNumActive();
    }
    public static int getMaxActive() {
    return ((BasicDataSource) ds).getMaxActive();
    }

    public static Connection getConnection() {
    try {
    return ds.getConnection();
    } catch(SQLException ex) {
    ex.printStackTrace();
    }
    return null;
    }

    public static final String DBCP_Driver_Class = "dbcp.driver_class";
    public static final String DBCP_ConnectionUrl = "dbcp.connection_url";
    public static final String DBCP_ConnectionUsername = "dbcp.connection_username";
    public static final String DBCP_ConnectionPassword = "dbcp.connection_password";
    public static final String DBCP_InitialSize = "dbcp.initial_size";
    public static final String DBCP_MaxIdle = "dbcp.max_idle";
    public static final String DBCP_MaxActive = "dbcp.max_active";
    public static DataSource inited(Properties props) {
    if(ds == null) ds = setupDataSource(props);
    Connection conn = null;
    Statement stmt = null;
    ResultSet rset = null;
    try {
    conn = ds.getConnection();
    stmt = conn.createStatement();
    } catch(SQLException e) {
    e.printStackTrace();
    } finally {
    try { if(rset != null) rset.close(); } catch(Exception e) { }
    try { if(stmt != null) stmt.close(); } catch(Exception e) { }
    try { if(conn != null) conn.close(); } catch(Exception e) { }
    }

    return ds;
    }
    private static DataSource setupDataSource(Properties props) {
    String cls = props.getProperty(DBCP_Driver_Class);
    String connectURI = props.getProperty(DBCP_ConnectionUrl);
    String userName = props.getProperty(DBCP_ConnectionUsername);
    String passWord = props.getProperty(DBCP_ConnectionPassword );
    String initalSize = props.getProperty(DBCP_InitialSize);
    int intInitalSize = 100;
    try {
    intInitalSize = Integer.parseInt(initalSize);
    } catch(Exception ex) {
    }
    String maxIdle = props.getProperty(DBCP_MaxIdle);
    int intMaxIdle = 10;
    try {
    intMaxIdle = Integer.parseInt(maxIdle);
    } catch(Exception ex) {
    }
    String maxActive = props.getProperty(DBCP_MaxActive);
    int intMaxActive = 10;
    try {
    intMaxActive = Integer.parseInt(maxActive);
    } catch(Exception ex) {
    }

    BasicDataSource bds = new BasicDataSource();
    bds.setDriverClassName(cls);
    bds.setUrl(connectURI);
    bds.setUsername(userName);
    bds.setPassword(passWord);
    bds.setInitialSize(intInitalSize);
    //﹍て渺钡计秖
    bds.setMaxIdle(intMaxIdle);
    // 程idle计
    bds.setDefaultAutoCommit(false);
    bds.setMaxActive(intMaxActive);
    //程祇计
    factory = new DataSourceConnectionFactory(bds);
    return bds;
    }
    }
    實現接口在hibernate中配置dbcp..
    package app.db;
    import org.hibernate.connection.ConnectionProvider;
    public class DbcpConnectionProvider implements ConnectionProvider {
    private static final Log log = LogFactory.getLog(DbcpConnectionProvider.class);
    private DataSource ds;
    public void configure(Properties arg0) throws HibernateException {
    // TODO Auto-generated method stub
    try {
    Properties props1 = new Properties();
    props1.setProperty(DbcpDataSource.DBCP_Driver_Class,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_Driver_Class));
    props1.setProperty(DbcpDataSource.DBCP_ConnectionUrl,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_ConnectionUrl));
    props1.setProperty(
    DbcpDataSource.DBCP_ConnectionUsername,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_ConnectionUsername));
    props1.setProperty(
    DbcpDataSource.DBCP_ConnectionPassword,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_ConnectionPassword));
    props1.setProperty(DbcpDataSource.DBCP_InitialSize,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_InitialSize));
    props1.setProperty(DbcpDataSource.DBCP_MaxIdle,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_MaxIdle));
    props1.setProperty(DbcpDataSource.DBCP_MaxActive,
    (String) app.core.Environment
    .getAttribute(DbcpDataSource.DBCP_MaxActive));
    ds = DbcpDataSource.inited(props1);
    app.core.Environment.setAppDataSource(ds);

    } catch (Exception ex) {
    ex.printStackTrace();
    log.error(ex);
    }
    }
    public Connection getConnection() throws SQLException {
    // TODO Auto-generated method stub
    return ds.getConnection();
    }
    public void closeConnection(Connection arg0) throws SQLException {
    // TODO Auto-generated method stub
    arg0.close();
    }
    public void close() throws HibernateException {
    // TODO Auto-generated method stub
    try {
    ((BasicDataSource) ds).close();
    } catch(Exception ex) {
    ex.printStackTrace();
    log.error(ex);
    }
    }
    public boolean supportsAggressiveRelease() {
    // TODO Auto-generated method stub
    return false;
    }
    }
    非最精簡的代碼,自已整理




    你可能感兴趣的:(数据库连接池)