10.10 使用连接管理池管理连接
数据库连接的建立及关闭是耗费系统资源的操作,在多层结构的应用环境中,这种耗时对系统性能影响尤为明显。通过前面的介绍(DriverManager 获得连接)获得数据库连接,一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完毕后立即关闭连接。频繁打开、关闭连接将造成系统性能低下。
数据库连接池的解决方案:
当程序启动时,系统建立足够的数据库连接,并将这些连接组成一个连接池。每次应用程序请求数据库连接时,无须冲核心打开连接,而是从连接池中取出已有连接使用,使用完毕后不在关闭数据库连接,而是直接将连接归还给连接池。通过使用连接池,将大大提高程序的运行效率。
对于资源的情况,有一个通用设计模式:资源池(Resource Poll),用于解决资源频繁请求、释放造成性能下降。为了解决数据库连接的频繁请求、释放,JDBC 2.0 规范引入数据库连接池技术。数据库连接池是 Connection 对象的工厂。数据库连接池的常用参数如下:
1、数据库的初始连接数
2、连接池最大连接数
3、连接池最小连接数
4、连接池每次增加的容量
JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口。该接口通常由商用服务器等提供实现,也有一些开源组织提供实现(如 DDBCP 和 C3P0 等)。
一、DBCP 数据源
DBCP 是 Apache 软件基金组织下的开源连接池实现,该连接池依赖于该组织下的另一个开源系统:common-pool. 如果需要使用该连接池的实现,则应在系统中增加两个.jar 文件。
(1)common-dbcp.jar: 连接池的实现。
(2)commons-pool.jar: 连接池实现的依赖库。
登录 http://commons.apache.org/ 站点即可下载 commons-pool.zip 和 commons-dbcp.zip 两个压缩文件,解压缩两个文件即可得到上面的两个 JAR 文件。问了在程序中使用这两个 JAR 文件,应该把它们添加到系统的类加载路径中(比如 CLASSPATH 环境遍历中)。
Tomcat 的连接池正是采用的该连接池实现的。数据库连接池既可以于应用服务器整合使用,也可以由下面的程序独立使用。下面代码示范了使用 DBCP 来获取数据库连接方式:
// 创建数据源对象
var ds=new BasicDataSource();
// 设置连接池所需要的驱动
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 设置数据库的 URL
ds.setUrl("jdbc:mysql://localhost:3306/javaee?useSSL=false&serverTimezone=UTC");
// 设置连接数据库的用户名
ds.setUsername("root");
// 设置连接数据库的密码
ds.setPassword("pass");
// 设置连接池的初始连接数
ds.setInitialSize(5);
// 设置来连接池最多可以由多少个活动连接数
ds.setMaxActive(20);
// 设置连接池最少有两个空闲的连接
ds.setMinIdle(2);
数据源和数据库连接不同,数据源无须创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。即使说对于一个应用,上面的代码只要求执行一次即可。建议把 ds 设置成 static 修饰,程序所有需要数据库连接的地方直接访问 ds 对象,并获取数据库的连接即可。通过 DataSource 获取数据库连接的代码:
// 通过数据源获取数据库连接
Connection conn=ds.getConnection();
访问结束后,程序需要关闭数据库连接:
// 释放数据库连接
conn.close();
上面的代码并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给连接池,让其他客户端可以使用该连接。
二、C3P0 数据源
相比直之下,C3P0 数据源的性能更好,Hibernate 推荐使用该连接池。C3P0 连接池不仅可以自动清理不在使用的 Connection,还可以自动清理 Statement 和 ResultSet.C3P0 连接池需要 1.3 以上版本。如果需要使用 C3P0 连接池,则应在系统中增加如下 JAR 文件。
★c3p0-0.9.1.2.jar:C3P0 连接池的实现
登录 http://sourceforge.net/projects/c3p0/ 站点下载 C3P0 的数据源的最新版本,下载后即得到一个 c3p0-0.9.1.2.bin.zip 文件,解压该文件,即可得到上面的 JAR 文件。
// 创建数据源对象
var ds=new CombopooledDataSource();
// 设置连接池所需要的驱动
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 设置数据库的 URL
ds.setJdbcUrl("jdbc:mysql://localhost:3306/javaee?useSSL=false&serverTimezone=UTC");
// 设置连接数据库的用户名
ds.setUsername("root");
// 设置连接数据库的密码
ds.setPassword("pass");
// 设置来连接池的最大连接数
ds.setMaxPoolSize(40);
// 设置来连接池的最小连接数
ds.setMinPoolSize(40);
// 设置连接池的初始连接数
ds.setInitialPoolSize(10);
// 设置连接池的最大缓存 Statement
ds.setMaxStatemrnts(180);
一旦获得了 C3P0 连接池之后,程序可以通过如下代码来获取数据库的连接:
Connection conn=ds.getConnection();
__EOF__