数据库连接池C3P0学习

2023-11-11

数据库连接池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:

 

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

 

 2.ConnectionPool

 

package com.study.pool;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class ConnectionPool {
	private DataSource ds;
	private static ConnectionPool pool;
	private ConnectionPool(){
		ds = new ComboPooledDataSource();
	}
	public static final ConnectionPool getInstance(){
		if(pool==null){
			try{
				pool = new ConnectionPool();
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		return pool;
	}
	public synchronized final Connection getConnection() {  
		try {
			return ds.getConnection();
		} catch (SQLException e) {     
			e.printStackTrace();
		}
		return null;
	}
	
}

 

 3.PoolThread

 

package com.study.pool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class PoolThread extends Thread {
	@Override
	public void run(){
		ConnectionPool pool = ConnectionPool.getInstance();
		Connection con = null;
		PreparedStatement stmt= null;
		ResultSet rs = null;
		try{
			con = pool.getConnection();
			stmt = con.prepareStatement("select sysdate as nowtime from dual");
			rs = stmt.executeQuery();
			while(rs.next()){
				System.out.println(Thread.currentThread().getId()+"---------------开始"+rs.getString("nowtime"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				rs.close();
				stmt.close();
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getId()+"--------结束");
	}
}

 

 4.PoolMain

 

package com.study.pool;

public class PoolMain {

	/**
	 * 数据源缓冲池 实例练习
	 */
	public static void main(String[] args) {
		System.out.println("缓冲池模拟开始");
		PoolThread[] threads = new PoolThread[50];
		for(int i=0;i<threads.length;i++){
			threads[i] = new PoolThread();
		}
		for(int i=0;i<threads.length;i++){
			threads[i].start();
		}
	}

}

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库连接池C3P0学习 的相关文章

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 使用 Android 发送 HTTP Post 请求

    我一直在尝试从 SO 和其他网站上的大量示例中学习 但我无法弄清楚为什么我编写的示例不起作用 我正在构建一个小型概念验证应用程序 它可以识别语音并将其 文本 作为 POST 请求发送到 node js 服务器 我已确认语音识别有效 并且服务
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo

随机推荐

  • 计算机提示msvcp110.dll文件丢失下载安装修复教程

    电脑打开一个浏览器后在顶部网址栏目输入 dll修复程序 site 按下键盘的回车键打开前往 下载完成的修复工具需要对其进行压缩 解压好了以后打开工具 打开修复工具后 可以看到右边修复与检测的项目 点击一下开始检测电脑丢失的dll系统文件 检
  • 回来喂马啊

    继续回来喂马了 1 这么多天没更新的原因 断更也有一段时间了 近期实在是业务过于繁忙 上线了项目之后又开启了新的项目 确实很难顾得上 毕竟一下班回家就累的只想躺平哈哈哈哈 还有一个原因是新项目和后续的项目转用了SpringBoot Myba
  • ios中的锁

    代码测试可参考 只有实际写过才能更好的理解 在平时开发中我们经常会使用多线程 多线程为我们带来了很大便利 也提高了程序的执行效率 但同时也带来数据风险 当至少有两个线程同时访问同一个变量 而且至少其中有一个是写操作时 就发生了Data ra
  • java中栈的使用

    栈是什么 栈的定义 栈是我们经常使用的一种线性数据结构 它是只能通过一端操作的线性表 我们可以操作的一端称之为栈顶 另一端则称之为栈底 特点 栈通常和队列作比较 队列的特点是先进先出 栈的特点则是先进后出 举一个例子 比如说我们生活中洗碗
  • hdu 6181 Two Paths

    Problem acm hdu edu cn showproblem php pid 6181 Reference Dijkstra应用之次短路 2017 Multi University Training Contest 10 1011
  • 基于微信小程序的在线小说阅读系统,附数据库、教程

    1 功能简介 Java基于微信小程序的在线小说阅读系统 微信小程序的在线小说阅读系统 系统的整体功能需求分为两部分 第一部分主要是后台的功能 后台功能主要有小说信息管理 注册用户管理 系统系统等功能 微信小程序主要分为首页 分类和我的三部分
  • ArcSDE 日志文件表(一)

    今天跟大家介绍一下ArcSDE日志文件表 一直都想好好研究一下这块 因为基本上不太受大家重视 感兴趣的用户不是很多 但是一旦出现多用户并发查询或者版本操作的时候 这个东西就显得非常重要了 而且根据不同的用户场景设定不同的日志类型 对相关效率
  • HTTP超文本传输协议

    HTTP协议 超文本传输协议 注意 我们以后编写Servlet类时 不会直接继承GenericServlet类 因为我们是B S结构系统 这种系统是基于HTTP超文本传输协议的 他有一个专门的Servlet类 我们编程的时候要继承HttpS
  • esp8266 esp12 AT指令连接wifi热点联网,HTTP获取OneNET物联网平台消息,控制四路远程开关

    esp8266 esp12 使用AT指令联网非常方便 很适合应对已经开发好的成品需要增加联网功能的需求 使用AT指令进行开发 大多数是产品已经开发好 只需要增加小数据量的联网功能 而且不想对既有成品有较大的方案修改 下面来使用 esp826
  • AttributeError: 'generator' object has no attribute 'next'

    在python3 x版本中 python2 x的g next 函数已经更名为g next 所以只需要将g next 换成g next 就可以了 如果你觉得g next 太丑 使用next g 也能达到相同效果
  • CentOS7中使用yum安装Nginx的方法

    最近无意间发现Nginx官方提供了Yum源 因此写个文章记录下 1 添加源 默认情况Centos7中无Nginx的源 最近发现Nginx官网提供了Centos的源地址 因此可以如下执行命令添加源 sudo rpm Uvh http ngin
  • Ubuntu18.04下安装OpenCV4.2.0与Opencv_contrib(图文详细报错总结)

    Ubuntu18 04下安装OpenCV4 2 0与Opencv contrib 图文详细 前期准备 环境依赖 Cmake 编译器 依赖环境 Python环境 streamer环境 图像处理依赖 安装OpenCV 编译OpenCV 配置cm
  • Unity3d--AR/MR 技术

    一 作业要求 1 图片识别与建模 2 虚拟按键小游戏 3 开发城市定向越野运动 MR 游戏 可选 游戏要求 准备 选择为每个用户准备一套拼图图片 含干扰图片 按一定策略发布到目标位置 随机位置偏移 越野地图一张 开始游戏 玩家在起点 用手机
  • EMC测试项目——辐射骚扰

    辐射骚扰 Radiation emission 主要是指能量以电磁波的形式由源发射到空间 或能量以电磁波形式在空间传播的现象 辐射骚扰是电磁兼容的重要内容 也是测试最不容易通过且最难整改的项目 辐射骚扰超标的产品可能引起周围装置 设备或系统
  • rust腐蚀怎么建立单机服务器_腐蚀rust新手入门指南 腐蚀rust怎么开始游戏

    如何开始游戏 巴拉巴拉那么多现在开始步入正轨吧 点击find game 就进入了服务器列表 在这里你可以加入官方的服务器 热闹但高延迟 也可以加入玩家自己设置的服务器 有些服务器不怎么友好详情请看贴吧举报贴 1 官方服务器列表 2和3 玩家
  • 解决JDK版本导致JMeter无法启动问题

    最近在做一个秒杀系统练习时 需要使用JMeter进行压力测试 但是安装JMeter后 出现了以下错误 很明显是JDK的版本问题导致的 但是我又不想改变系统的JDK版本 所以可以下载高版本的JDK 无需改变系统的JDK版本 直接在bin jm
  • nginx-代理多个服务

    目录 1 主机多Ip 1 1单网卡多ip主机配置 1 2修改default conf 1 3server1 conf 1 3server2 conf 1 4测试文件 1 4重启测试 2 主机多端口 2 1server1 conf 2 2se
  • 三个不等_高中数学竞赛常用的不等式归纳(续一)

    当 时 代入 23 为减少篇幅就不在此写出完整的 23式 下同 式得 即 25 25 式正是 22 九 加权不等式 9 1若 且 则 26 26 式就是加权的均值不等式 简称加权不等式 26 式形式直接理解为 几何均值不大于算术均值 十 赫
  • 2020第八届“泰迪杯”特等奖(基于 BERT 深度语言模型的“智慧政务”文本挖掘应用)

    目录 1绪论 1 1 智慧政务 文本挖掘的意义 1 2 智慧政务 文本挖掘的目标 1 3语言智能的里程碑技术 BERT 深度语言模型介绍 1 4本文的总体框架 1 5本文主要的创新之处 2基于 BERT 模型的留言自动分类 2 1任务介绍与
  • 数据库连接池C3P0学习

    数据库连接池C3P0框架是个非常优异的开源jar 高性能的管理着数据源 这里只讨论程序本身负责数据源 不讨论容器管理 一 实现方式 C3P0有三种方式实现 1 自己动手写代码 实现数据源 例如 在类路径下配置一个属性文件 config pr