C3P0连接池自诞生以来在Java Web领域反响甚好,业已成为hibenate框架推荐的连接池。谁知人红是非多,C3P0在大型应用场合中暴露了越来越多的局限性,包括但不限于下列几点:
1、C3P0管理池内连接时没有采取LRU排队规则(最久未使用算法),意味着C3P0未能将数据库性能调到最优。
2、在处理大批量数据的时候,C3P0对耗时操作过于容忍,致使容易出现线程死锁的状况。
3、C3P0不支持监控功能,外界难以实时跟踪连接池的运行情况,不利于按需分配和调度系统资源。
就上面几点问题的看法因人而异,对老外来说,他们国家人口不多,一百年都难得遇上这种严苛的条件,考虑超大规模的数据处理纯属杞人忧天。但对国人来说,数据库里的业务记录动辄以千万计,亿级以上的海量数据也不罕见,此时一点一滴的性能差距汇总起来就可能出大问题。然而C3P0源自国外,人家才懒得搭理这茬事;再说,此等关键要害岂能由外人扼住咽喉?当然要自己掌握核心技术才让人放心,于是阿里巴巴公司推出了国产的开源连接池Druid,该连接池立足于本国国情,在诸多方面加以调整和优化,比C3P0更适用于国内的业务系统。
Druid的用法近似于C3P0,它拥有自己的连接池工具DruidDataSource,该工具的常见方法列举如下:
setDriverClassName:设置连接池的数据库驱动。
setUrl:设置数据库的连接地址。
setUsername:设置数据库的用户名。
setPassword:设置数据库的密码。
setInitialSize:设置连接池的初始大小。
setMinIdle:设置连接池大小的下限。
setMaxActive:设置连接池大小的上限。
setRemoveAbandoned:设置是否抛弃已超时的连接。
setRemoveAbandonedTimeout:设置超时的时间间隔,单位秒。如果某连接超过该时间仍未释放,则会被自动回收。
setMaxWait:设置获取连接所允许的等待时间,单位毫秒。超过该时间将不再获取连接。
setTimeBetweenEvictionRunsMillis:设置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒。
setValidationQuery:设置检测连接是否有效的SQL语句。
setTestWhileIdle:当空闲时是否需要进行有效性测试。建议设置为true,保证安全性。
setTestOnBorrow:设置为true,表示申请连接时将调用validationQuery方法来检测连接是否有效。
getDbType:获取数据库的名称。
getActiveCount:获取活跃连接的数量。
getConnectCount:获取已连上连接的数量。
getPoolingCount:获取空闲连接的数量。
getConnection:从连接池中获取一个连接,连接类型为DruidPooledConnection。
close:关闭连接池。

至于Druid的编码过程,则依然分成两个步骤:初始化连接池、从连接池中取出一个连接处理,分别说明如下:
1、初始化连接池
该步骤首先创建Druid连接池的对象,再依次调用相关方法设置详细的参数信息,包括数据库驱动、连接地址、用户名、密码,以及与连接池有关的规格参数。下面是初始化Druid连接池的代码例子:

	private static DruidDataSource dataSource; // 声明Druid连接池的对象
// 初始化连接池
private static void initDataSource() {
dataSource = new DruidDataSource(); // 创建Druid连接池
dataSource.setDriverClassName(driver_class); // 设置连接池的数据库驱动
dataSource.setUrl(dbUrl); // 设置数据库的连接地址
dataSource.setUsername(dbUserName); // 设置数据库的用户名
dataSource.setPassword(dbPassword); // 设置数据库的密码
dataSource.setInitialSize(1); // 设置连接池的初始大小
dataSource.setMinIdle(1); // 设置连接池大小的下限
dataSource.setMaxActive(20); // 设置连接池大小的上限
}

  

2、从连接池中取出一个连接处理
注意该步骤的getConnection方法拿到的是DruidPooledConnection类型的连接对象,再根据该连接创建对应的报告,并开展后续的数据库操作。为方便观察连接池的运行情况,可在其中添加几个连接池的检测方法,例如getActiveCount、getConnectCount、getPoolingCount等等。修改后的数据库操作代码示例如下:

	// 显示性别分组
private static void showRecordGroupBySex() {
String sql = "select sex,count(1) count from teacher group by sex order by sex asc";
// 从连接池中获取连接、创建连接的报告、命令报告执行指定的SQL语句
try (DruidPooledConnection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) { // 循环遍历结果集里面的所有记录
int sex = rs.getInt("sex"); // 获取指定字段的整型值
int count = rs.getInt("count"); // 获取指定字段的整型值
String desc = String.format("%s老师有%d位;", sex==0 ? "男" : "女", count);
System.out.print(desc);
}
System.out.println("\ngetActiveCount="+dataSource.getActiveCount()); // 获取活跃连接的数量
System.out.println("getConnectCount="+dataSource.getConnectCount()); // 获取已连上连接的数量
System.out.println("getPoolingCount="+dataSource.getPoolingCount()); // 获取空闲连接的数量
} catch (SQLException e) {
e.printStackTrace();
}
}

然后由外部反复调用以上的showRecordGroupBySex方法,假设准备测试连续的三次数据库操作,则外部的调用代码如下所示:

		for (int i=0; i<3; i++) { // 多次操作数据库
showRecordGroupBySex(); // 显示性别分组
}

运行包含上面代码的测试程序,观察到下面的输出日志:

男老师有2位;女老师有3位;
getActiveCount=1
getConnectCount=1
getPoolingCount=0
男老师有2位;女老师有3位;
getActiveCount=1
getConnectCount=2
getPoolingCount=0
男老师有2位;女老师有3位;
getActiveCount=1
getConnectCount=3
getPoolingCount=0

由日志可见,getActiveCount方法返回了当前正在使用的连接数量,getConnectCount方法返回了曾经连上与已经连上的连接总数,getPoolingCount返回了连接池中剩余的连接数量。


更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(一百五十一)Druid连接池的用法的更多相关文章

  1. Java开发笔记(五十一)多态的发生场景

    江湖上传闻,面向对象之所以厉害,是因为它拥有封装.继承与多态三项神技,只要三板斧一出,号令天下谁敢不从.前面费了老大的劲才讲清楚封装和继承,那么多态又是怎样的神乎其神呢?下面先通过一个简单的例子来说明 ...

  2. Java开发笔记(五十三)关键字final的用法

    前面介绍了多态的相关用法,可以看到一个子类从父类继承之后,便能假借父类的名义到处晃悠.这种机制在正常情况之下没啥问题,但有时为了预防意外发生,往往只接受当事人来处理,不希望它的儿子乃至孙子来瞎掺和.可 ...

  3. Java开发笔记(八十一)如何使用系统自带的注解

    之前介绍继承的时候,提到对于子类而言,父类的普通方法可以重写也可以不重写,但是父类的抽象方法是必须重写的,如果不重写,编译器就直接在子类名称那里显示红叉报错.例如,以前演示抽象类用法之时,曾经把Chi ...

  4. Java开发笔记(三十一)字符类型的表达

    前面介绍的Java编程,要么是与数字有关的计算,要么是与逻辑有关的推理,充其量只能实现计算器和状态机.若想让Java运用于更广阔的业务领域,就得使其支撑更加血肉丰满的业务场景,而丰满的前提是能够表达大 ...

  5. Java开发笔记(四十一)日历工具Calendar

    前面的文章提到,Date是Java最早的日期工具,估计当时的设计师是个技术宅男,未经过充分调研就拍脑袋写下了Date的源码,造成该工具存在先天不足,比如getYear方法返回的不是纯正的公元纪年.ge ...

  6. Java开发笔记(五十)几种开放性修饰符

    前面介绍子类继承父类的时候,提到了public(公共)和private(私有)两个修饰符,其中public表示它所修饰的实体是允许外部访问的:而private表示它所修饰的实体不允许外部访问,只能在当 ...

  7. Java开发笔记(五十二)对象的类型检查

    前面介绍了类的多态性,来自于鸡类的实例chicken,既能用来表达公鸡实例,也能用来表达母鸡实例.可是这导致了一个问题,假如在call方法内部需要手工判断输入参数属于公鸡实例还是母鸡实例,那该如何是好 ...

  8. Java开发笔记(五十四)内部类和嵌套类

    通常情况下,一个Java代码文件只定义一个类,即使两个类是父类与子类的关系,也要把它们拆成两个代码文件分别定义.可是有些事物相互之间密切联系,又不同于父子类的继承关系,比如一棵树会开很多花朵,这些花儿 ...

  9. Java开发笔记(五十五)关键字static的用法

    前面介绍嵌套类的时候讲到了关键字static,用static修饰类,该类就变成了嵌套类.从嵌套类的用法可知,其它地方访问嵌套类之时,无需动态创建外层类的实例,直接创建嵌套类的实例就行.其实static ...

随机推荐

  1. 线程太多导致socket连接池爆满,进程启动不了

    Issue: 某部机上跟其它机器的连接有问题,ping可以通,telnet端口不通,可以其它机器可以连接到该机器上的进程. java应用启动不起来,产生以下错误. java.net.SocketExc ...

  2. ent 基本使用五 schema介绍

    ent 提供了自动生成schema 但是,我们可以基于生成schema 进行扩展,schema 主要包含以下配置 实体的字段(或者属性)比如 user 的name 以及age 实体的边(关系),比如u ...

  3. asyncapi 指南

    asyncapi 是可以用来创建异步机器可读定义api的指南,我们可以用来创建事件驱动的架构. 说明 asyncapi 的定义类似openapi,目前指南版本为2.0,很值得学习下 参考资料 http ...

  4. 使用packer 打包nodegui 应用

    packer 是nodegui 团队提供的专门用来打包noodegui 应用程序的工具 安装packer yarn 方式安装 yarn add @nodegui/packer 效果 [fsevents ...

  5. JS稀奇古怪题目

    JS稀奇古怪题目: 1.操作对象属性优先级高于普通赋值操作 var a = { n: 1 }; var b = a; //操作对象属性优先级高于普通赋值操作 a.x = a = { n: 2 }; c ...

  6. 【luoguP4720】【模板】扩展卢卡斯

    快速阶乘与(扩展)卢卡斯定理 \(p\)为质数时 考虑 \(n!~mod~p\) 的性质 当\(n>>p\)时,不妨将\(n!\)中的因子\(p\)提出来 \(n!\) 可以写成 \(a* ...

  7. UE4的联网系统研究

    1. 物体复制 具体细节可参考官网内容:http://api.unrealengine.com/CHN/Gameplay/Networking/index.html 这里只挑部分点来展开. 首先,分为 ...

  8. CSS样式的引入方式

    test.css div{ color:yellow; } 在html中引入 <link href="test.css" type="text/css" ...

  9. ZooKeeper入门实战教程(一)-介绍与核心概念

    1.ZooKeeper介绍与核心概念1.1 简介ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务.在学习zookeeper之前,先要对分布式系统的概念有所了解,否则你将完全不知道 ...

  10. mysql左连接查询结果不准确

    现有四张表 表(1)res_resource_catalog 表(2)res_catalog_classify 表(3)res_resource_classify 表(4)res_resource_m ...