数据库连接的建立及关闭是耗费系统资源的操作,在多层结构的应用环境中,这种耗时对系统性能影响尤为明显。通过前面的介绍(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();