13.9 使用连接池管理连接

13.9 使用连接池管理连接

数据库连接的建立及关闭是极耗费系统资源的操作,在多层结构的应用环境中,这种资源的耗费对系统性能影响尤为明显。通过前面介绍的方式(通过DriverManager获取连接)获得的数据库连接,个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完后立即关闭连接。频繁地打开、关闭连接将造成系统性能低下
数据库连接池的解决方案是:当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接组成一个连接池。每次应用程序请求数据库连接时,无须重新打开连接,而是从连接池中取出已有的连接使用,使用完后不再关闭数据库连接,而是直接将连接归还给连接池。通过使用连接池,将大大提高程序的运行效率
对于共享资源的情况,有一个通用的设计模式:资源池(Resource pool),用于解决资源的频繁请求、释放所造成的性能下降。为了解决数据库连接的频繁请求、释放,JDBC2.0规范引入了数据库连接池技术。数据库连接池是Connection对象的工厂。数据库连接池的常用参数如下。

  • 数据库的初始连接数。
  • 连接池的最大连接数。
  • 连接池的最小连接数。
  • 连接池每次增加的容量。

JDBC的数据库连接池使用javax.sql.DataSource来表示, DataSource只是一个接口,该接口通常由商用服务器(如WebLogicWebSphere)等提供实现,也有一些开源组织提供实现(如DBCPC3PO等)。
提示:
DataSource通常被称为数据源,它包含连接池和连接池管理两个部分,但习惯上也经常把DataSource称为连接池。

13.9.1 DBCP数据源

DBCPApache软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统common-pool如果需要使用该连接池实现,则应在系统中增加如下两个jar文件。

  • commons-dbcp. jar:连接池的实现。
  • commons-pool jar:连接池实现的依赖库。

登录http://commons.apache.org/站点即可下载commons-pool.zipcommons-dbcp.zip两个压缩文件解压缩这两个文件即可得到上面提到的两个JAR文件。为了在程序中使用这两个JAR文件,应该把它们添加到系统的类加载路径中(比如添加到 CLASSPATH环境变量中)
Tomcat的连接池正是采用该连接池实现的。数据库连接池既可以与应用服务器整合使用,也可以由应用程序独立使用。下面的代码片段示范了使用DBCP来获得数据库连接的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//创建数据源对象
BasicDataSource ds= new BasicDataSource();
//设置连接池所需的驱动
ds.setDriverclassName("com.mysql.jdbc.Driver");
//设置连接数据库的URL
ds. setUrl("jdbc:mysql://localhost:3306/javaee");
//设置连接数据库的用户名
ds.setUsername("root");
//设置连接数据库的密码
ds.setPassword("pass")
//设置连接池的初始连接数
ds.setInitialsize(5);
//设置连接池最多可有多少个活动连接数
ds.setMaxActive(20);
//设置连接池中最少有2个空闲的连接
ds.setMinIdle(2)

数据源和数据库连接不同,数据源无须创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。也就是说,对于一个应用,上面代码只要执行一次即可。建议把上面程序中的ds设置成static成员变量,并且在应用开始时立即初始化数据源对象,程序中所有需要获取数据库连接的地方直接访问该ds对象,并获取数据库连接即可。通过DataSource获取数据库连接的代码示例如下:

1
2
//通过数据源获取数据库连接
Connection conn=ds.getConnection();

当数据库访问结束后,程序还是像以前一样关闭数据库连接,如下代码所示:

1
2
//释放数据库连接
conn.close();

但上面代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给连接池,让其他客端可以使用该连接。

13.9.2 C3P0数据源

相比之下,C3P0数据源性能更胜一筹, Hibernate就推荐使用该连接池。C3P0连接池不仅可以自动清理不再使用的Connection,还可以自动清理StatementResultsetC3P0连接池需要版本为1.3以上的JRE,推荐使用1.4以上的JRE。如果需要使用C3P0连接池,则应在系统中增加如下JAR文件。

  • c3p0-0.9.1.2jar:C3PO连接池的实现。

下载C3P0数据源

登录C2P0站点即可下载C3P0数据源的最新版本,下载后得到一个c3p0-0.91.2bin.zip文件(版本号可能有区别),解压缩该文件,即可得到上面提到的JAR文件。
下面代码通过C3P0连接池获得数据库连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//创建连接池实例
ComboPooledDataSource ds=new ComboPooledDataSource();
//设置连接池连接数据库所需的驱动
ds.setDriverClass("com.mysql.jdbc.Driver");
//设置连接数据库的URL
ds.setJdbcUrl("jdbc:mysql://localhost:3306/javaee");
//设置连接数据库的用户名
ds.setUser("root");
//设置连接数据库的密码
ds.setPassword("32147");
//设置连接池的最大连接数
ds.setMaxPoolSize(40);
//设置连接池的最小连接数
ds.setMinPoolSize(2);
//设置连接池的初始连接数
ds.setInitialPoolSize(10);
//设置连接池的缓存Statement的最大数
ds.setMaxstatements(180);

在程序中创建C3P0连接池的方法与前面介绍的创建DBCP连接池的方法基本类似,此处不再解释。一旦获取了C3P0连接池之后,程序同样可以通过如下代码来获取数据库连接。

1
2
//获得数据库连接
Conection conn=ds.getConnection();