Java开发笔记(一百五十)C3P0链接池的用法

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:关闭链接池。
引入链接池以后,完整的数据库操做流程分解成了两大步骤:初始化链接池、从链接池中取出一个链接处理,下面分别予以介绍。
一、初始化链接池
该步骤首先建立C3P0链接池的对象,再依次调用相关方法设置详细的参数信息,包括数据库驱动、链接地址、用户名、密码,以及与链接池有关的规格参数。下面是初始化C3P0链接池的代码例子:html

	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); // 设置链接池的初始大小
	}

  

二、从链接池中取出一个链接处理
除了一开始调用链接池的getConnection获取链接以外,该步骤剩余的操做过程与JDBC原有流程保持一致,即得到数据库链接以后,一样要建立链接的报告,而后命令报告执行SQL语句。下面是经过链接池操做数据库的代码例子:java

	// 显示性别分组
	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链接池正常工做。sql

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



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

相关文章
相关标签/搜索