常用Java数据库连接池
概述
在这里所谓的数据库连接是指通过网络协议与数据库服务之间建立的TCP连接。通常,与数据库服务进行通信的网络协议无需由应用程序本身实现,原因有三:
- 实现复杂度大,需要充分理解和掌握相应的通信协议。
- 代码难以复用,每个应用程序都需要独立实现一套对应的网络协议(不同公司之间,同一公司的不同技术栈之间难以复用实现相同协议的代码)
- 性能难以保证,不同的网络协议实现可能存在巨大的性能差距。
正因为如此,所以现实的实现方式是:
首先,定义网络协议标准,这样只要支持这个标准协议的数据库就可以使用相应的客户端与之通信。
其次,将实现这个标准协议的客户端独立为一个通信库,这样只需要在应用程序中使用这个通信组件库就可以方便地实现与数据库进行交互。
通常,我们将实现了网络协议的通信库称之为数据库驱动程序。当然,对于不同的编程语言,需要对应编写相应的数据库驱动实现。以与关系型数据库通信为例,在Java中实现的驱动程序为JDBC,Python中的驱动程序为MySQLdb。
由于通过TCP与数据库建立网络连接的代价非常高昂,而且耗时(TCP建立连接需要“三次握手”,断开连接需要“四次握手”)。所以在实践中通常不直接单独使用连接进行数据库操作,而是使用连接池的方式,这主要是处于以下两方面的考虑:
- 应用程序本身需要更低的响应时间,如果每次数据库操作都需要经过“建立连接->通信(增删改查)->断开连接”这个过程,那么势必会导致响应延时的增加。
- 避免服务器资源被耗尽,随着业务量的增大,对应的数据库操作必然会随之增加,如果对客户端的连接数不加以控制,可能会导致数据库服务器的CPU和内存资源被大量的网络连接快速耗尽,这样将导致服务不可用。

在Java中使用得比较流行的数据库连接池主要有:DBCP,c3p0,druid。
另外,不论使用什么连接池,低层都是使用JDBC连接,即:在应用程序中都需要加载JDBC驱动程序。
DBCP
https://commons.apache.org/proper/commons-dbcp/index.html
DBCP是Apache下独立的数据库连接池组件,在Tomcat中使用的连接池组件就是DBCP,支持JDBC3,JDBC4。关于更多JDBC版本信息,详见:https://en.wikipedia.org/wiki/Java_Database_Connectivity。
c3p0
http://www.mchange.com/projects/c3p0/
使用c3p0有多种方式,如:既可以直接使用API方式配置c3p0,也可以通过文件的方式进行配置,配置文件有2种形式:properties或xml文件。
<dependencies>
<!-- JDBC驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
<!-- c3p0连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- 日志组件 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
1.使用Java API方式配置c3p0
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "com.mysql.jdbc.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl("jdbc:mysql://host:port/db");
cpds.setUser("username");
cpds.setPassword("password");
cpds.setMinPoolSize(5);
cpds.setMaxPoolSize(20);
cpds.setAcquireIncrement(5);
// 直接从连接池中获取连接
Connection conn = cpds.getConnection();
query(conn);
// 关闭连接池
// cpds.close();
2.使用文件方式配置c3p0
2.1 使用c3p0.properties文件进行配置
需要在classpath路径下添加配置文件:c3p0.properties,内容如下:
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://host:port/db
c3p0.user=root
c3p0.password=
c3p0.minPoolSize=5
c3p0.maxPoolSize=20
c3p0.acquireIncrement=5
在应用程序中只需要直接创建ComboPooledDataSource对象即可(c3p0会自动从classpath加载c3p0.properties中的配置信息):
ComboPooledDataSource cpds = new ComboPooledDataSource();
Connection conn = cpds.getConnection();
query(conn);
cpds.close();
注意: 使用c3p0.properties作为配置文件时,每个参数的name前缀必须是“c3p0”,如:“c3p0.driverClass=com.mysql.jdbc.Driver”。
2.2 使用c3p0-config.xml文件进行配置
使用这种方式会比使用c3p0.properties更加高级,支持配置多个数据源,同样需要在classpath路径下添加文件:c3p0-config.xml。
<c3p0-config>
<!-- 默认数据源 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://host:port/db</property>
<property name="user">username</property>
<property name="password">password</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
<property name="acquireIncrement">5</property>
</default-config>
<!-- 定义带名称的数据源 -->
<named-config name="myDataSource">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test_jdbc</property>
<property name="user">root</property>
<property name="password"></property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
<property name="acquireIncrement">5</property>
</named-config>
</c3p0-config>
// 使用默认数据源
// ComboPooledDataSource cpds = new ComboPooledDataSource();
// 使用指定名称的数据源
ComboPooledDataSource cpds = new ComboPooledDataSource("myDataSource");
Connection conn = cpds.getConnection();
query(conn);
cpds.close();
3.c3p0常用配置
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://host:port/db</property>
<property name="user">username</property>
<property name="password">password</property>
<!-- 连接池初始化时创建的连接数,默认值: 3 -->
<property name="initialPoolSize">3</property>
<!-- 连接池保持的最小连接数,默认值: 3 -->
<property name="minPoolSize">3</property>
<!-- 连接池中拥有的最大连接数,如果获得新连接时会使连接总数超过这个值则不会再获取新连接,而是等待其他连接释放。 -->
<property name="maxPoolSize">15</property>
<!-- 连接池在无空闲连接可用时一次性创建的新数据库连接数,默认值: 3 -->
<property name="acquireIncrement">3</property>
<!-- 连接的最大空闲时间,如果超过这个时间,某个数据库连接还没有被使用,则会断开掉这个连接。为0,则永远不会断开连接。默认值: 0,单位: 秒 -->
<property name="maxIdleTime">0</property>
<!-- 连接测试语句 -->
<property name="preferredTestQuery">select 1</property>
<!-- 用来配置测试空闲连接的间隔时间。可以用来解决MySQL 8小时断开连接的问题。因为它保证连接池会每隔一定时间对空闲连接进行一次测试,从而保证有效的空闲连接能每隔一定时间访问一次数据库,将MySQL8小时无会话的状态打破。为0则不测试。默认值:0,单位: 秒 -->
<property name="idleConnectionTestPeriod">30</property>
<!-- 连接池在获得新连接失败时重试的次数,如果小于等于0则无限重试直至连接获得成功。默认值: 30 -->
<property name="acquireRetryAttempts">30</property>
<!-- 连接池在获得新连接时的间隔时间,默认值: 1000,单位: 毫秒 -->
<property name="acquireRetryDelay">1000</property>
</default-config>
</c3p0-config>
druid
https://github.com/alibaba/druid
阿里开源的druid不单纯是一个连接池,还添加了监控功能,目前已经是非常受推崇的连接池组件,详细配置参数请参考官网。
当然,还存在一些其他的数据库连接池实现,例如:Tomcat自己就实现了一个连接池组件,根据官方的说法,这个连接池正是为了在Tomcat中替换DBCP,详见:https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html。
【参考】
http://josh-persistence.iteye.com/blog/2229929 深入浅出数据库连接池c3p0
常用Java数据库连接池的更多相关文章
- 主流Java数据库连接池分析(C3P0,DBCP,TomcatPool,BoneCP,Druid)
主流数据库连接池 常用的主流开源数据库连接池有C3P0.DBCP.Tomcat Jdbc Pool.BoneCP.Druid等 C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDB ...
- Java数据库连接池封装与用法
Java数据库连接池封装与用法 修改于抄袭版本,那货写的有点BUG,两个类,一个用法 ConnectionPool类: package com.vl.sql; import java.sql.Conn ...
- Java数据库连接池
转载过来的,最近在做一个小网站,准备使用这种方法. Java jdbc数据库连接池总结! 1. 引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及, ...
- 一个JAVA数据库连接池实现源码
原文链接:http://www.open-open.com/lib/view/open1410875608164.html // // 一个效果非常不错的JAVA数据库连接池. // from:htt ...
- Java数据库连接池的几种配置方法(以MySQL数据库为例)
Java数据库连接池的几种配置方法(以MySQL数据库为例) 一.Tomcat配置数据源: 前提:需要将连接MySQL数据库驱动jar包放进Tomcat安装目录中common文件夹下的lib目录中 1 ...
- Java数据库连接池详解
http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html 对于共享资源,有一个很著名的设计模式:资源池(Resource P ...
- [转帖]为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用
为什么HikariCP被号称为性能最好的Java数据库连接池,如何配置使用 原创Clement-Xu 发布于2015-07-17 15:53:14 阅读数 57066 收藏 展开 HiKariCP是 ...
- 从零开始学 Java - 数据库连接池的选择 Druid
我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...
- [数据库连接池] Java数据库连接池--DBCP浅析.
前言对于数据库连接池, 想必大家都已经不再陌生, 这里仅仅设计Java中的两个常用数据库连接池: DBCP和C3P0(后续会更新). 一. 为何要使用数据库连接池假设网站一天有很大的访问量,数据库服务 ...
随机推荐
- HAOI2017 简要题解
「HAOI2017」新型城市化 题意 有一个 \(n\) 个点的无向图,其中只有 \(m\) 对点之间没有连边,保证这张图可以被分为至多两个团. 对于 \(m\) 对未连边的点对,判断有哪些点对满足将 ...
- [POJ 1637] Sightseeing tour(网络流)
题意 (混合图的欧拉回路判定) 给你一个既存在有向边, 又存在无向边的图. 问是否存在欧拉回路. \(N ≤ 200, M ≤ 1000\) 题解 难点在于无向边. 考虑每个点的度数限制. 我们先对无 ...
- Hdoj 1253.胜利大逃亡 题解
Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个ABC的立方体,可以被表示成A个B*C的矩 ...
- 【BZOJ4784】[ZJOI2017]仙人掌(Tarjan,动态规划)
[BZOJ4784][ZJOI2017]仙人掌(Tarjan,动态规划) 题面 BZOJ 洛谷 题解 显然如果原图不是仙人掌就无解. 如果原图是仙人掌,显然就是把环上的边给去掉,变成若干森林连边成为仙 ...
- 【BZOJ5213】[ZJOI2018]迷宫(神仙题)
[BZOJ5213][ZJOI2018]迷宫(神仙题) 题面 BZOJ 洛谷 题解 首先可以很容易的得到一个\(K\)个点的答案. 构建\(K\)个点分别表示\(mod\ K\)的余数.那么点\(i\ ...
- 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)
[LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...
- Linux安装Gitlab,附iSCSI分区挂载说明
因为Gitlab数据要存放在共享存储,所以本次配置的重头戏倒变成了挂载ISCSI了. OS:CentOS 7.2IP:172.16.1.191/192.168.2.191 iSCSI分Target(服 ...
- 【模板】ac自动机
本来是真的特别不想写这个的 但是有段时间洛谷天天智推这个可能是我太菜了 然后觉得这个也不难 乘着今早没事写下 来这保存下 方便下次食用 #include <bits/stdc++.h> u ...
- 【洛谷P3901】数列找不同
题目大意:给定一个长度为 N 的序列,每个点被染了一个颜色.现有 M 个询问,每个询问查询区间 [l,r] 内的点是否颜色都是不同的. 题解:莫队裸题. 直接维护区间颜色数,用 cnt[] 记录下区间 ...
- [NOIP2018]旅行(数据加强版)(图论+基环树)
数据范围多了2个0就是不一样,O(n^2)只能68分了.(其中60分是n=m+1和原题一样的做法送的),这题直接从NOIP难度变为NOI Plus难度了不说废话直接写题解:首先dfs一遍找到环,然后和 ...