详解C3P0(数据库连接池)
一、基本定义
C3P0是一个开源的JDBC连接池,它实现了数据源与JNDI绑定,支持JDBC3规范和实现了JDBC2的标准扩展说明的Connection和Statement池的DataSources对象。
即将用于连接数据库的连接整合在一起形成一个随取随用的数据库连接池(Connection pool)。
二、使用C3P0(数据库连接池)的必要性
当我们在进行基于数据库的web程序开发时,我们可以先在主程序(如Servlet、Bean)中通过JDBC中的DriverManager建立数据库连接,然后将要对数据库进行操作的sql语句封装到Statement中,最后在返回结果集后断开数据库连接。以上是较为传统的开发模式,然而用这种模式开发会埋下严重的安全隐患。
1.JDBC传统模式开发存在的主要问题
1.1>时间和内存资源消耗巨大
普通的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再根据JDBC代码(或配置文件)中的用户名和密码进行验证其正确性。这一过程一般会花费0.05~1s,一旦需要数据库连接的时候就必须向数据库请求一个,执行完后再断开连接。显然,如果同一个数据库在同一时间有数十人甚至上百人请求连接势必会占用大量的系统资源,严重的会导致服务器崩溃。
1.2>有内存泄漏的风险
因为每一次数据库连接使用完后都需要断开连接,但如果程序出现异常致使连接未能及时关闭,这样就可能导致内存泄漏,最终只能以重启数据库的方法来解决;
另外使用传统JDBC模式开发不能控制需要创建的连接数,系统一般会将资源大量分出给连接以防止资源不够用,如果连接数超出一定数量也会有极大的可能导致内存泄漏。
三、数据库连接池的详细说明
为了解决由使用传统开发模式创建连接导致的一系列问题,我们可以采用数据库连接池技术。
数据库连接池的基本原理就是为数据库建立一个缓冲池。在缓冲池中先创建指定数量的数据库连接,当有连接请求时就从缓冲池中取出处于“空闲”状态的连接,并将此连接标记为“忙碌”,直到该请求进程结束后,它所使用的连接才会重新回到“空闲”状态,并等待下一次请求调用。
从上面不难看出数据库连接池的主要作用就是负责分配、管理和释放数据库连接,它允许程序重复使用同一个现有的数据库连接,大大缩短了运行时间,提高了执行效率。
这里需要强调一点的是,数据库连接池中的连接数是在其初始化时根据c3p0-config.xml中的最小连接数来确定的,关于c3p0-config.xml我会在后文提供模板以供大家参考。当然,无论连接池的连接数是否有被使用,它都至少会保持最小连接数,如果请求连接数超过最小连接数也会根据c3p0-config.xml中指定的自增长数增加连接数直到达到最大连接数,这时如果请求连接数量还是大于连接池中的连接数的话,剩下的请求将会被放入等待队列直到有空闲连接出现。
这样一来,数据库连接池相较于传统JDBC模式等到请求发出才创建连接的做法有着显而易见的优势。
四、使用连接池的明显优势
1.资源的高效利用
由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销,减小了系统资源消耗的同时也提高了系统运行环境的平稳性。
2.更快的系统反应速度
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接可以避免数据库在连接初始化和释放过程所需的时间开销,从而减少了系统的响应时间,提高了系统的反应速度。
3.减少了资源独占的风险
新的资源分配手段对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置实现对某一应用最大可用数据库连接数的限制,避免了应用独占所有数据库资源的风险。
4.统一的连接管理,避免数据库连接泄露
在实现较为完善的数据库连接池时,可根据预先的占用超时设定,强制回收被占用连接,从而避免了常规数据库连接操作中可能出现的资源泄露。
——————————————我是一条优雅的分割线——————————————
虽然数据库连接池(Connection pool)种类很多,并不仅限于c3p0这一个,像DBCP、BoneCP、Proxool、SmartPool、MiniConnectionPoolManager等等都是较为常用的,c3p0只是其中较为优秀且使用人数较多的一款,因为标题的原因这里只说c3p0。
五、C3P0实操
1.导入jar包
主要是c3p0和mysql,其他根据需求添加
2.配置xml文件
下面是我配置的c3p0-config.xml,可以作为模板以供大家参考:
3. 一般c3p0-config.xml模板
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config><default-config><!--mysql数据库连接的各项参数--><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/day06</property><property name="user">root</property><property name="password">root</property><!--配置数据库连接池的初始连接数、最小链接数、获取连接数、最大连接数、最大空闲时间--><property name="initialPoolSize">10</property><property name="minPoolSize">10</property><property name="acquireIncrement">5</property><property name="maxPoolSize">100</property><property name="maxIdleTime">30</property></default-config>
</c3p0-config>
当然,除了以上这几种常用的参数设置以外,这里还有一份有关c3p0-config.xml参数的详细清单,如有需要可自行增加。
4.c3p0-config.xml参数清单
<c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候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> <!--强烈不建议使用该方法,将这个设置为true可能会导致一些微妙而奇怪的bug--> <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--> <property name="usesTraditionalReflectiveProxies">false</property> </default-config> </c3p0-config>
5.创建C3P0Util类
package com.c3p0.utils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class C3P0Util {//使用ComboPooledDataSource来生成DataSource的实例private static DataSource dataSource = new ComboPooledDataSource();//从连接池中获取连接public static Connection getConnection() {try {return dataSource.getConnection();} catch (SQLException e) {// TODO Auto-generated catch blockthrow new RuntimeException();}}//释放连接回连接池public static void release(Connection conn, Statement stmt, ResultSet rs) {if (rs != null) {try {rs.close();} catch (Exception e) {e.printStackTrace();}rs = null;}if (stmt != null) {try {stmt.close();} catch (Exception e) {e.printStackTrace();}stmt = null;}if (conn != null) {try {conn.close();} catch (Exception e) {e.printStackTrace();}conn = null;}} }
1.相较于JDBC,使用C3P0能够更加高效地建立与数据库的连接,尤其是在高并发随机访问数据库的时候;
2.C3P0通过dataSource.getConnection()从线程池中获取“空闲”连接,真正的数据库连接创建与释放则是由C3P0在后台自行完成的,我们只花费了获取和释放连接占用权的时间;
3.使用c3p0-config.xml代替原来JDBC硬编码的形式,提高了代码复用性。
详解C3P0(数据库连接池)相关推荐
- Java数据库开发与应用之MySQL数据库、JDBC操作数据库、C3P0数据库连接池,Java反射等
MySQL数据库,JDBC接口,MyBatis框架等,掌握的数据的存放和管理. Java数据库开发基础,介绍MySQL数据库.JDBC操作数据库.C3P0数据库连接池,Java反射等内容,进行油画商城 ...
- c3p0 数据库连接池
C3P0连接池 c3p0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.c3p0一般是与Hibernate,Spring等框架一块使用的,当然也可以 ...
- [原创]java WEB学习笔记80:Hibernate学习之路--- hibernate配置文件:JDBC 连接属性,C3P0 数据库连接池属性等...
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- php 内存池,内存详解: 详解PHP内存池中的存储层_php
php的内存管理器是分层(hierarchical)的.这个管理器共有三层:存储层(storage).堆(heap)层和 emalloc/efree 层.存储层通过 malloc().mmap() 等 ...
- 数据库连接池种类、C3P0数据库连接池、德鲁伊数据库连接池
数据库连接池种类 1.JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现 2.C3P0数据库连接池,速度相对较慢,稳 ...
- 数据库连接池及C3P0数据库连接池技术
数据库连接池(重要) 注意数据库连接池只是简化获得数据库连接对象和关流的部门 1.数据库连接池: 1.概念: 其实就是一个容器(在Java中就是集合),存在数据库连接的容器,当系统初始化好后,容器被创 ...
- 数据库连接池 DBCP和c3p0数据库连接池
一.数据库连接池 1. 什么是连接池 传统的开发模式下,Servlet处理用户的请求,找Dao查询数据,dao会创建与数据库之间的连接,完成数据查询后会关闭数据库的链接. 这样的方式会导致用户每次请求 ...
- ThreadPoolExecutor详解及线程池优化
前言 ThreadPoolExecutor在concurrent包下,是我们最常用的类之一.无论是做大数据的,还是写业务开发,对其透彻的理解以及如何发挥更好的性能,成为了我们在更好的coding道路上 ...
- 【JDBC】使用c3p0数据库连接池的各种报错警告
使用c3p0数据库连接池的各种报错警告 使用c3p0数据库连接池的时候,先导入了三个jar包在lib 文件夹中, c3p0-0.9.5.2.jar mchange-commons-java-0.2.3 ...
- C3P0数据库连接池的配置
在pom.xml文件中导入jar包 <dependency><groupId>com.mchange</groupId><artifactId>c3p0 ...
最新文章
- Nginx访问控制_IP访问控制(http_access_module)原理、局限性、解决方法讲解
- JavaScript有关的10个怪癖和秘密
- HTTP请求头中各字段解释
- java程序员的第二编程语言应该选什么?
- 一文读懂单目视觉SLAM分类方法~基于概率框架和非概率框架
- goquery php,golang:Goquery简单爬虫实例
- tomcat的acceptCount、maxThreads、connectionTimeout参数调整
- nginx跨域配置步骤
- XShell 6和Xftp6
- 计算机发展史的十大成就,我国在自然科学领域的十大成就都有哪些?
- pageadmin CMS网站建设教程:模板中如何实现信息数据共享
- File 与 MultipartFile概述
- Microsoft Visual Studio 2010升级Service Pack1问题
- 《临江仙》---摘抄
- m=m++到底发生了什么
- 编程比赛项目和时间汇总
- 上证指数(000001)股票历史数据,下载上证指数(000001历史数据
- 出现Whitelabel Error Page的解决方法(持续更新带图并总结了其他博文)
- 前端js解析识别图片二维码
- 【力扣周赛】第346场周赛
热门文章
- 区块链架构1.0、2.0与3.0梳理
- 算法设计与分析(第2版)屈婉玲 刘田 张立昂 王捍贫编著 第四章课后习题答案
- 超级详细的SIMATIC STEP7 V5.5安装
- emp和emn是什么文件_emn格式文件
- Activiti学习(二)之工作流的入门与流程实列
- java集成微信扫码登录
- 基于python和酷Q的QQ机器人开发实践(1)
- 『Java面经』简述 Java 的反射机制及其应用场景
- java 修改分辨率_JAVA程序分辨率修改及自适屏修改
- 一步一步学Repast 第二章(把界面显示出来2)