DBCP、c3p0、Druid三大连接池区别

一、连接池优势

如果一个项目中如果需要多个连接,如果一直获取连接,断开连接,这样比较浪费资源;

如果创建一个池,用池来管理Connection,这样就可以重复使用Connection。

有了池我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。

池就可以再利用这个Connection对象了。这里我们常用的连接池有三种,分别是:DBCP连接池、C3P0连接池和DRUID连接池;

二、DBCP连接池

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

使用连接池的第一项工作就是导包,这里需要的两个jar包分别是:

在使用写连接池工具类的时候,可以通过配置文件来连接数据库,配置文件中记录了连接数据库的驱动、URL、用户名和密码等信息;但要注意这里的文件后缀为:“.properties”。

把通过配置文件连接数据库的部分写在静态代码块中,随着类的加载只加载一次。出了连接数据库,还要提供一个获得数据源的方法和一个获取连接的方法;

下边是把连接池写成一个工具类的代码,写成工具类和直接使用的代码几乎相同,就不在重复的写了。

配置文件的部分内容:

代码:(配置文件的命名为:dbcp.properties)

public class DBCPUtils {
//首先定义私有的datasource
private static DataSource datasource;
//把配置文件部分放在静态代码块中,调用时直接加载
static{
try {
//加载文件
InputStream is=DBCPUtils.class.getClassLoader().getResourceAsStream("dbcp.properties");
//实例化properties集合
Properties prop=new Properties();
prop.load(is);
//首先加载核心类
datasource=BasicDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//提供获得数据源
public static DataSource getDataSource(){
return datasource;
}
//提供获得连接
public static Connection getConnection() throws SQLException{
return datasource.getConnection();
}
}

在写成工具类后都要对外提供一个数据源DateSource和一个连接Connection。作用是,如果我们在进行数据库操作的时候要是使用DBUtils类的时候,就要使用QueryRunner核心类,而这个类在进行与数据库连接的时候只要一句代码:QueryRunner qr=newQueryRunner(数据源);

通过连接池获得:DBCPUtils.getDataSource()获得。如果不使用DBUtils工具类,我们就可以直接通过DBCPUtils .getConnection()来直接获得连接。

三、C3P0连接池

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

使用连接池的第一项工作就是导包,这里需要的两个jar包分别是:

这种连接池在进行数据库的连接的时候有两种连接方法:使用配置文件和不使用配置文件两种。

当然使用配置文件的时候代码要简介的多,配置文件中同样是记录了连接数据库的驱动、URL、用户名和密码等信息。

(1)不使用配置文件的代码:三个步骤:

<1>、导入核心类:ComboPooledDataSource

<2>、基本的四项设置,也就是设置驱动,URL,用户名和密码等四项。

<3>、其他四项。代码如下:

public class c3p0_test01 {
public static void main(String[] args) throws Exception {
//导入一个核心类
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//基本四项设置
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/eeday09");
dataSource.setUser("root");
dataSource.setPassword("123");
//其他四项设置
dataSource.setInitialPoolSize(10); //初始化连接个数
dataSource.setMaxPoolSize(40); //最大链接数
dataSource.setMinPoolSize(5); //设置最小链接数
dataSource.setAcquireIncrement(2); //设置每次增加的连接数
Connection conn=dataSource.getConnection(); //进行数据库连接
System.out.println(conn);
}

(2)如果使用配置文件连接数据库,其中配置文件中的内容为:

使用配置文件进行连接的写法如下:

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import com.mchange.v2.c3p0.ComboPooledDataSource; public class C3P0Utils {
//1、提供私有化的数据源 使用默认设置
private static ComboPooledDataSource datasource=new ComboPooledDataSource();
//使用命名配置
//private static ComboPooledDataSource datasource =new ComboPooledDataSource("itheima");
//2.提供对外的数据源
public static DataSource getDataSource(){
return datasource;
}
//3.提供对外的链接
public static Connection getConnection() throws SQLException{
return datasource.getConnection();
}
}

在写成工具类后都要对外提供一个数据源DateSource和一个连接Connection。作用是,如果我们在进行数据库操作的时候要是使用DBUtils类的时候,就要使用QueryRunner核心类,而这个类在进行与数据库连接的时候只要一句代码:QueryRunner qr=newQueryRunner(数据源);

我们可以通过连接池获得:C3P0Utils.getDataSource() 获得。如果不使用DBUtils工具类,我们就可以直接通过C3P0Utils.getConnection()来直接获得连接。

四、Druid连接池

Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个 SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。Druid针对Oracle和MySql做了特别优化,比如Oracle的PS Cache内存占用优化,MySql的ping检测优化。Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。简单SQL语句用时10微秒以内,复杂SQL用时30微秒。通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的。

使用步骤:

1,使用连接池的第一项工作就是导包,这里需要的jar包分别是:druid-1.1.4.jar   1.1.4

2,druid.properties 文件内容:

# 配置数据库的连接参数
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=root

# 配置连接池的参数
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

3,连接池工具类:

/**
1)创建私有静态数据源成员变量DataSource ds
2)在静态代码块中创建连接池
a)创建属性对象
b)从类路径下加载属性文件,得到输入流对象
c)通过工厂类创建一个数据源
3)创建公有的得到数据源的方法getDataSource()
4)创建得到连接对象的方法 getConnection()
5)创建释放资源的方法 close()
*/ /**
* 连接池的工具类
*/
public class DataSourceUtils {
//创建一个成员变量
private static DataSource ds;
/**
* 加载的代码写在静态代码块中
*/
static {
try {
Properties info = new Properties();
//加载类路径下,即src目录下的druid.properties这个文件
info.load(DataSourceUtils.class.getResourceAsStream("/druid.properties")); //读取属性文件创建连接池
ds = DruidDataSourceFactory.createDataSource(info);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到数据源
*/
public static DataSource getDataSource() {
return ds;
}
/**
* 得到连接对象
*/
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 释放资源
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection conn, Statement stmt) {
close(conn, stmt, null);
}
}

4,数据源工具类的使用:

public class DemoAdd {
   public static void main(String[] args) {
       //1. 创建连接对象,通过连接池工具类
       Connection conn = null;
       PreparedStatement ps = null;
       int row = 0;
       try {
           conn = DataSourceUtils.getConnection();
           //2. 创建语句对象
          ps = conn.prepareStatement("INSERT INTO student values(null,?,?,?)");
          ps.setString(1,"张辽");
          ps.setInt(2,1);
          ps.setString(3,"194-06-16");
          //3. 使用executeUpdate()写入到数据库
           row = ps.executeUpdate();
      } catch (SQLException e) {
           e.printStackTrace();
      } finally {
           //4. 释放资源
           DataSourceUtils.close(conn, ps);
      }
       System.out.println("添加了" + row);
  }
}

五、三者区别

我们从连接池配置的基本配置、关键配置、性能配置等主要配置来分析:

1,基本配置

基本配置是指连接池进行数据库连接的四个基本必需配置:
传递给JDBC驱动的用于连接数据库的用户名、密码、URL以及驱动类名。

注:在Druid连接池的配置中,driverClassName可配可不配,如果不配置会根据url自动识别dbType(数据库类型),然后选择相应的driverClassName。

2,关键配置

为了发挥数据库连接池的作用,在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数 据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池 请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
最小连接数:是数据库一直保持的数据库连接数,所以如果应用程序对数据库连接的使用量不大,将有大量的数据库资源被浪费。
初始化连接数:连接池启动时创建的初始化数据库连接数量。
最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入到等待队列中。
最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0或者负数使得无限等待(根据不同连接池配置)。

注1:在DBCP连接池的配置中,还有一个maxIdle的属性,表示最大空闲连接数,超过的空闲连接将被释放,默认值为8。对应的该属性在Druid连接池已不再使用,配置了也没有效果,c3p0连接池则没有对应的属性。

注2:数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连接。如果当前池中正在使用的连接数等 于maxActive,则会等待一段时间,等待其他操作释放掉某一个连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没 有达到maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在连接使用完毕后,不是将其物理连接关闭,而 是将其放入池中等待其他操作复用。

3,性能配置

(1)预缓存设置:

  即是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle。JDBC的标准参数,用以控制数据源内加载的 PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池,所以设置这个参数需要考 虑到多方面的因素。
  单个连接拥有的最大缓存数:要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100

(2)连接有效性检测设置:

  连接池内部有机制判断,如果当前的总的连接数少于miniIdle,则会建立新的空闲连接,以保证连接数得到miniIdle。如果当前连接池中某 个连接在空闲了timeBetweenEvictionRunsMillis时间后任然没有使用,则被物理性的关闭掉。有些数据库连接的时候有超时限制 (mysql连接在8小时后断开),或者由于网络中断等原因,连接池的连接会出现失效的情况,这时候设置一个testWhileIdle参数为true, 可以保证连接池内部定时检测连接的可用性,不可用的连接会被抛弃或者重建,最大情况的保证从连接池中得到的Connection对象是可用的。当然,为了 保证绝对的可用性,你也可以使用testOnBorrow为true(即在获取Connection对象时检测其可用性),不过这样会影响性能。

(3)超时连接关闭设置:

  removeAbandoned参数,用来检测到当前使用的连接是否发生了连接泄露,所以在代码内部就假定如果一个连接建立连接的时间很长,则将其认定为泄露,继而强制将其关闭掉。

(4)c3p0重连设置:

  设置获取连接失败后,是否重新连接以及间隔时间。

六、DBCP、C3P0、DRUID三大连接池属性说明表

1,DBCP 属性说明表

2,C3P0  属性说明表

(3)DRUID 属性说明表

DBCP、c3p0、Druid三大连接池区别的更多相关文章

  1. c3p0,dbcp与druid 三大连接池的区别[转]

    说到druid,这个是在开源中国开源项目中看到的,说是比较好的数据连接池.于是乎就看看.扯淡就到这. 下面就讲讲用的比较多的数据库连接池.(其实我最先接触的是dbcp这个) 1)DBCP DBCP是一 ...

  2. SpringBoot整合Druid数据连接池

    SpringBoot整合Druid数据连接池 Druid是什么? Druid是Alibaba开源的的数据库连接池.Druid能够提供强大的监控和扩展功能. 在哪里下载druid maven中央仓库: ...

  3. spring下,druid,c3p0,proxool,dbcp四个数据连接池的使用和配置

    由于那天Oracle的数据连接是只能使用dbcp的数据库连接池才连接上了,所以决定试一下当下所有得数据库连接池连接orcale和mysql,先上代码 配置文件的代码 #================ ...

  4. 总结spring下配置dbcp,c3p0,proxool数据源链接池

    转载自 http://hiok.blog.sohu.com/66253191.html applicationContext-datasource-jdbc.xml <?xml version= ...

  5. 【SpringBoot笔记】SpringBoot整合Druid数据连接池

    废话少说,按SpringBoot的老套路来. [step1]:添加依赖 <!-- 数据库连接池 --> <dependency> <groupId>com.alib ...

  6. Hive使用druid做连接池代码实现

    配置文档 hive_jdbc_url=jdbc:hive2://192.168.0.22:10000/default hive.dbname=xxxxx hive_jdbc_username=root ...

  7. spring boot配置druid数据连接池

    Druid是阿里巴巴开源项目中一个数据库连接池. Druid是一个jdbc组合,包含三个部分, 1.DruidDriver代理Driver,能够提供基于Filter-Chain模式得插件体系2.Dru ...

  8. 【Mysql】SpringBoot阿里Druid数据源连接池配置

    一.pom.xml添加 <!-- 配置数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> &l ...

  9. DBCP之----"数据库"与"连接池"的连接建立过程

    1 public class DBCPTest { 2 /* 3 * 使用BasicDataSource类,通过url, 4 和diverClass,username,password, 5 几个参数 ...

随机推荐

  1. 如何取消一个目录的git初始化

    一不小心把我的整个home目录都初始化为git仓库了,通过执行删除.git命令,可以恢复 rm -rf .git

  2. CodeForces - 586D Phillip and Trains 搜索。vis 剪枝。

    http://codeforces.com/problemset/problem/586/D 题意:有一个3*n(n<100)的隧道.一个人在最左边,要走到最右边,每次他先向右移动一格,再上下移 ...

  3. 自己实现一个简单的网络音乐mp3播放器

    大繁至简,把思路搞清楚才是最重要的,如何去做依托于使用什么来实现这项功能 列出我使用的基本类 NSURLSessionDataTask 数据获取类 NSFileHandle 数据缓存和数据读取类 Au ...

  4. 在选定合适的执行引擎之后,通过敏感字段重写模块改写 SQL 查询,将其中的敏感字段根据隐藏策略(如只显示后四位)进行替换。而敏感字段的隐藏策略存储在 ranger 中,数据管理人员可以在权限管理服务页面设置各种字段的敏感等级,敏感等级会自动映射为 ranger 中的隐藏策略。

    https://mp.weixin.qq.com/s/4G_OvlD_5uYr0o2m-qPW-Q 有赞大数据平台安全建设实践 原创: 有赞技术 有赞coder 昨天

  5. LRU算法 缓存淘汰策略

    四种实现方式 LRU 1.1. 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也 ...

  6. 理解CopyOnWriteArrayList

    CopyOnWriteArrayList,顾名思义,Write的时候总是要Copy,也就是说对于任何可变的操作(add.set.remove)都是伴随复制这个动作的 A thread-safe var ...

  7. mysql 数据操作 多表查询 子查询 带IN关键字的子查询

    1 带IN关键字的子查询 #查询平均年龄在25岁以上的部门名关键点部门名 以查询员工表的dep_id的结果 当作另外一条sql语句查询条件使用 in (sql语句) mysql ; +-------- ...

  8. 010-mac下常用命令

    1.查看某个端口是否运行 lsof -i tcp:port lsof -i:8080 2.强制关闭进程 kill -9 PID

  9. mysql查看和修改注释

    MySQL查看注释,MySQL修改注释,mysql查看注释,mysql修改注释 1.给大家做演示,这里随便创建一张学生表,代码如下: CREATE TABLE `student` ( `id` int ...

  10. spring boot整合JWT例子

    application.properties jwt.expire_time=3600000 jwt.secret=MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjY34DFDSS ...