数据库连接池C3P0学习

2024-05-25 18:32

本文主要是介绍数据库连接池C3P0学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数据库连接池C3P0框架是个非常优异的开源jar,高性能的管理着数据源,这里只讨论程序本身负责数据源,不讨论容器管理。

 

一、实现方式:

C3P0有三种方式实现:

1.自己动手写代码,实现数据源

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

driverClass=xxx

jdbcUrl=xxx

user=xxx

password=xxx

...

 

然后代码中实现

 

Properties props = new Properties();

InputStream in = Thread.class.getResourceAsStream("config.properties");

props.load(in);

in.close();

 

ComboPooledDataSource cpds = new ComboPooledDataSource();

cpds.setDriverClass(props.getProperty("driverClass"));

cpds.setJdbcUrl(props.getProperty("jdbcUrl"));

cpds.setUser(props.getProperty("user"));

cpds.setPassword(props.getProperty("password"));

...

这里实现了一个数据源。

 

也可以这样配置,在类路径下配置一个xml文件,config.xml

 

<config>

<source name="source1">

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

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

<property name="url">xxx</property>

<property name="driverClass">xxx</property>

</source>

 

<source name="source2">

...

</source>

</config>

 

 

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

 

2.配置默认的熟悉文件

类路径下提供一个c3p0.properties文件(不能改名)

配置如下:

 

c3p0.driverClass=com.mysql.jdbc.Driver

c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc

c3p0.user=root

c3p0.password=java

...
上面只提供了最基本的配置项,其他配置项参照  文档配置,记得是c3p0.后面加属性名就是了,最后初始化数据源的方式就是这样简单:
...
DataSource  ds = new ComboPooledDataSource();
return ds;
...
然后就可以使用数据源了,C3P0会对c3p0.properties进行自动解析的
3.路径下提供一个c3p0-config.xml文件  

 

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

 

 

<c3p0-config>

  <default-config>   

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

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

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

    <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>

 

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

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

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

    <property name="minPoolSize">10</property>

  </default-config>

 

  <named-config name="mySource">

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

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

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

    <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>

 

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

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

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

    <property name="minPoolSize">10</property>

  </named-config>

</c3p0-config>

 

...

DataSource  ds = new ComboPooledDataSource("mySource");

return ds;

...

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

 

二、部分参数配置说明:

 

 

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(不建议使用)

 

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

 

 

三、示例:

示例采用第二种方式:

1.c3p0.properties:

 

Java代码   收藏代码
  1. #驱动  
  2. c3p0.driverClass=com.mysql.jdbc.Driver  
  3. #地址  
  4. c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc  
  5. #用户名  
  6. c3p0.user=root  
  7. #密码  
  8. c3p0.password=lovejava  
  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.ConnectionPool

 

Java代码   收藏代码
  1. package com.study.pool;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.SQLException;  
  5.   
  6. import javax.sql.DataSource;  
  7.   
  8. import com.mchange.v2.c3p0.ComboPooledDataSource;  
  9.   
  10. public class ConnectionPool {  
  11.     private DataSource ds;  
  12.     private static ConnectionPool pool;  
  13.     private ConnectionPool(){  
  14.         ds = new ComboPooledDataSource();  
  15.     }  
  16.     public static final ConnectionPool getInstance(){  
  17.         if(pool==null){  
  18.             try{  
  19.                 pool = new ConnectionPool();  
  20.             }catch (Exception e) {  
  21.                 e.printStackTrace();  
  22.             }  
  23.         }  
  24.         return pool;  
  25.     }  
  26.     public synchronized final Connection getConnection() {    
  27.         try {  
  28.             return ds.getConnection();  
  29.         } catch (SQLException e) {       
  30.             e.printStackTrace();  
  31.         }  
  32.         return null;  
  33.     }  
  34.       
  35. }  

 

 3.PoolThread

 

Java代码   收藏代码
  1. package com.study.pool;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7.   
  8. public class PoolThread extends Thread {  
  9.     @Override  
  10.     public void run(){  
  11.         ConnectionPool pool = ConnectionPool.getInstance();  
  12.         Connection con = null;  
  13.         PreparedStatement stmt= null;  
  14.         ResultSet rs = null;  
  15.         try{  
  16.             con = pool.getConnection();  
  17.             stmt = con.prepareStatement("select sysdate as nowtime from dual");  
  18.             rs = stmt.executeQuery();  
  19.             while(rs.next()){  
  20.                 System.out.println(Thread.currentThread().getId()+"---------------开始"+rs.getString("nowtime"));  
  21.             }  
  22.         } catch (Exception e) {  
  23.             e.printStackTrace();  
  24.         }finally{  
  25.             try {  
  26.                 rs.close();  
  27.                 stmt.close();  
  28.                 con.close();  
  29.             } catch (SQLException e) {  
  30.                 e.printStackTrace();  
  31.             }  
  32.         }  
  33.         System.out.println(Thread.currentThread().getId()+"--------结束");  
  34.     }  
  35. }  

 

 4.PoolMain

 

Java代码   收藏代码
  1. package com.study.pool;  
  2.   
  3. public class PoolMain {  
  4.   
  5.     /** 
  6.      * 数据源缓冲池 实例练习 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         System.out.println("缓冲池模拟开始");  
  10.         PoolThread[] threads = new PoolThread[50];  
  11.         for(int i=0;i<threads.length;i++){  
  12.             threads[i] = new PoolThread();  
  13.         }  
  14.         for(int i=0;i<threads.length;i++){  
  15.             threads[i].start();  
  16.         }  
  17.     }  
  18.   
  19. }  

原文转载:http://haoran-10.iteye.com/blog/1753332

这篇关于数据库连接池C3P0学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002289

相关文章

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se