JDBC既制定统一标准兼容了多种数据库,又利用预报告堵上了SQL注入漏洞,照理说已经很完善了,可是人算不如天算,它在性能方面不尽如人意。问题出在数据库连接的管理上,按照正常流程,每次操作完数据库,都要关闭连接,无论是代码里手工关闭,还是由try语句自动关闭。如果没有及时关闭数据库连接,就会长时间占用有限的数据库内存,致使无谓的系统资源浪费。然而频繁开关数据库连接也有毛病,因为每次获取操作都要CPU处理,经常连接数据库会加重CPU的负担。看来内存与CPU像是一对难兄难弟,不管怎么做都会影响其中一个,正所谓鱼与熊掌不可兼得。
其实连接跟线程的情况相似,线程也很头疼频繁创建导致的资源开销,为此Java早早就设计了线程池机制,事先在一个池子中容纳若干线程,需要使用线程时便从中挑一根线程执行任务,任务做完再归还线程,如此实现了线程资源的循环利用,有效提高了系统的整体运行效率。既然线程们组建了线程池这个大家庭,那么连接们能否也组成连接池的大家庭呢?Java固然自带了线程池工具,却未能推出类似的连接池工具,于是各种第三方的连接池蜂拥而起,例如DBCP、C3P0、Proxool等等,其中应用广泛的当数C3P0。
C3P0是一个开源的数据库连接池,它支持JDBC3规范和JDBC2的标准扩展。若要在Java工程中运用C3P0,得先导入它的jar包,比如c3p0-0.9.5.4.jar,同时还要导入该jar包依赖的mchange-commons-java-0.2.16.jar,也就是一共导入两个jar文件。使用C3P0很简单,掌握ComboPooledDataSource类的用法就够了,该类的常见方法说明如下:
setDriverClass:设置连接池的数据库驱动。
setJdbcUrl:设置数据库的连接地址。
setUser:设置数据库的用户名。
setPassword:设置数据库的密码。
setMaxPoolSize:设置连接池大小的上限。
setMinPoolSize:设置连接池大小的下限。
setInitialPoolSize:设置连接池的初始大小。
setMaxStatements:设置报告的最大个数。
setCheckoutTimeout:设置获取连接的等待时间,单位毫秒。当连接池中的所有连接都被占用的时候,新请求想获取连接就必须等待,等待现有连接被释放后才能获取空闲连接。默认为0表示一直等待下去。
setMaxIdleTime:设置最大空闲时间,单位秒。如果某个连接超过该时间仍未使用,则会被自动回收。默认为0表示不判断是否超时,也就是永不回收。
getConnection:从连接池中获取一个连接。
close:关闭连接池。
引入连接池之后,完整的数据库操作流程分解成了两大步骤:初始化连接池、从连接池中取出一个连接处理,下面分别予以介绍。
1、初始化连接池
该步骤首先创建C3P0连接池的对象,再依次调用相关方法设置详细的参数信息,包括数据库驱动、连接地址、用户名、密码,以及与连接池有关的规格参数。下面是初始化C3P0连接池的代码例子:

   private static ComboPooledDataSource dataSource; // 声明C3P0连接池的对象// 初始化连接池private static void initDataSource() {dataSource = new ComboPooledDataSource(); // 创建C3P0连接池try {dataSource.setDriverClass(driver_class); // 设置连接池的数据库驱动} catch (PropertyVetoException e) {e.printStackTrace();}dataSource.setJdbcUrl(dbUrl); // 设置数据库的连接地址dataSource.setUser(dbUserName); // 设置数据库的用户名dataSource.setPassword(dbPassword); // 设置数据库的密码dataSource.setMaxPoolSize(10); // 设置连接池大小的上限dataSource.setMinPoolSize(1); // 设置连接池大小的下限dataSource.setInitialPoolSize(3); // 设置连接池的初始大小}

  

2、从连接池中取出一个连接处理
除了一开始调用连接池的getConnection获取连接之外,该步骤剩余的操作过程与JDBC原有流程保持一致,即获得数据库连接之后,同样要创建连接的报告,然后命令报告执行SQL语句。下面是通过连接池操作数据库的代码例子:

 // 显示性别分组private static void showRecordGroupBySex() {String sql = "select sex,count(1) count from teacher group by sex order by sex asc";// 从连接池中获取连接、创建连接的报告、命令报告执行指定的SQL语句try (Connection 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);}} catch (SQLException e) {e.printStackTrace();}}

整合连接池的初始化和具体操作的代码,运行包含整合代码之内的测试程序,观察如下日志可知C3P0连接池正常工作。

男老师有2位;女老师有3位;  


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

转载于:https://www.cnblogs.com/pinlantu/p/11525758.html

Java开发笔记(一百五十)C3P0连接池的用法相关推荐

  1. Java开发笔记(五十六)利用枚举类型实现高级常量

    前面介绍了联合利用final和static可实现常量的定义,该方式用于简单的常量倒还凑合,要是用于复杂的.安全性高的常量,那就力不从心了.例如以下几种情况,final结合static的方式便缺乏应对之 ...

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

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

  3. Android开发笔记(五十九)巧用传感器

    传感器Sensor 传感器是Android用来感知周围环境以及运动信息的工具.因为具体的感应信息依赖于相关硬件,所以虽然Android提供了众多的感应器,但不是每部手机都能支持这么多感应器,恰恰相反, ...

  4. Android开发笔记(五十四)数据共享接口ContentProvider

    ContentProvider 前面几节介绍了进程间通信的几种方式,包括消息包级别的Messenger.接口调用级别的AIDL.启动页面/服务级别的Notification,还有就是本节这个数据库级别 ...

  5. Android开发笔记(五十二)通知推送Notification

    PendingIntent 准备工作复习一下PendingIntent,前面的博文< Android开发笔记(五十)定时器AlarmManager>已经提到了它.PendingIntent ...

  6. Android开发笔记(五十八)铃声与震动

    拖动条SeekBar SeekBar继承自进度条ProcessBar,有关ProcessBar的介绍见<Android开发笔记(四十九)异步任务处理AsyncTask>.SeekBar与P ...

  7. Java开发笔记(八十六)通过缓冲区读写文件

    前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作"字符流I/O",其中字母I代表输 ...

  8. Java开发笔记(八十八)文件字节I/O流

    前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...

  9. Android开发笔记(五十五)手机设备基本操作

    获取手机基本信息 手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息. 与电话有关的信息可由TelephonyManager类获得,常用的参数与对应的方法如下所示: 网络运营商名称 ...

  10. Android开发笔记(五十六)摄像头拍照

    相机Camera Camera是直接操作摄像头硬件的工具类.常用的方法如下: getNumberOfCameras : 获取本机的摄像头数目 open : 打开摄像头,默认打开后置摄像头.如果有多个摄 ...

最新文章

  1. Django博客系统注册(图形验证码接口设计和定义)
  2. GitHub推出云端IDE,几秒完成开发环境配置,今后可以在浏览器里使用VS Code了
  3. mysql 存储引擎 介绍
  4. DSP unresolved symbol问题的解决
  5. DLL入门浅析(3)——从DLL中导出变量
  6. HMM和CRF 条件随机场详解
  7. java简单密码验证程序
  8. C++ 的 allocator类 提供类型化的内存分配以及对象的分配和撤销
  9. java swing 图片切换_在一个界面中要实现图片切换,用java要肿么实现??
  10. 蜗牛角上争天地——吴清源大师、名人、棋魂
  11. 99%的游戏主播都在用什么录屏软件?
  12. 学校源码php,闪灵CMS学校建站系统(含小程序) v5.0 bulid20200319_php免费源码
  13. 计算机wps函数的使用,WPS表格中IF函数使用的技巧
  14. 五菱宏光MINI EV,重走“小米”路
  15. html 手机语音聊天,好用的手机语音聊天软件推荐
  16. 计算机英语作文50词左右带翻译,找十篇英语作文,带翻译,50个词
  17. 聊一聊Java如何接入招行一网通支付功能
  18. java国际化之时区问题处理
  19. 今天的Java笔试题
  20. Mac下添加Chrome插件

热门文章

  1. centos 6.5 编译php mysql5.6_CentOS6.5 编译安装PHP5.6(apache模块)
  2. 中虚数怎么表示_虚数是负数的平方根,为什么在三次方程中才出现的呢?|高中篇3...
  3. HIVE数据导入MYSQL实现方式
  4. Spring Boot @ServletComponentScan 扫描 @WebServlet、@WebFilter、@WebListener
  5. php 服务器监控源码,PHP自动Get监控源码
  6. vba取一列数中非0的行_vba excel怎么获取指定工作表的行数、列数
  7. 阶段3 2.Spring_04.Spring的常用注解_6 用于注入数据的注解
  8. Codeforces 1110D. Jongmah 动态规划
  9. pyhton基础中的要点一
  10. MongoDb学习(四)--Repository