连接池原理
连接池的基本工作原理
1、 基本概念及原理
public class DBManager {
/** 获得连接对象*/
public static Connection getCon(){
Connection con=null;
try {
Class.forName(driver); //加载驱动类
//获得连接对象
con=DriverManager.getConnection(url,user,pwd);
}catch (Exception e) {
System.out.println(e.Message());
}
return con;
}
}
}
public class StudentDAO {
/**** 添加学生信息*/
public void addStudent(Student stu){
Connection con =DBManager.getCon();
//………………
}
}
由上面的分析可以看出,每次调用addStudent(Student stu) 都会新创建一个连接对象, 对数据库连接资源的管理非常低效。对于共享资源,有一个很著名的设计模式:资源池 (Resource Pool) 。该模式正是为了解决资源的频繁分配/释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量/使用情况,为系统开发/测试及性能调整提供依据。
连接池关键问题分析
1、 并发问题
为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java 语言自身提供了对并发管理的支持,使用synchronized 关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized 关键字,如:
public synchronized Connection getConnection() { }
2、 多数据库服务器和多用户
对于大型的企业级应用,常常需要同时连接不同的数据库(如连接Oracle 和Sybase) 。如何连接不同的数据库呢? 我们采用的策略是:设计一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url 地址()?用户名()?密码()等信息。
如:
sqlDriver=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver:// 172.21.15.123:5000;DataBaseName=HR
user=sa
pwd=sa
oracelDriver=oracle.jdbc.driver.OracleDriver
url= jdbc:oracle:@localhost:1521:orcl;DataBaseName=gams
user=sa
pwd=123456
根据资源文件提供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连接池。
对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url 地址,但具有不同用户名和密码的数据库连接信息。
如:
url= jdbc:sqlserver:// 172.21.15.123:5000;DataBaseName=HR; user=yang; password=yang321
url= jdbc:sqlserver:// 172.21.15.123:5000;DataBaseName=HR; user=lijun; password=lijun123
url= jdbc:sqlserver:// 172.21.15.123:5000;DataBaseName=HR; user=wantao; password=wangtao111
2、 连接池的分配与释放
连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。
对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接存放到一个空闲池中。每当用户请求一个连接时,首先检查空闲池内有没有空闲连接。如果有就分配给用户,如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户. 使用完连接对象后再返还给空闲池
3、 连接池的配置与维护
连接池中到底应该放置多少连接,才能使系统的性能最佳? 系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快; 如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。
如何确保连接池中的最小连接数呢? 有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接, 以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。
4、 连接池的实现
第一种: 连接固定的数据库
该连接池只能使用固定用户创建 连接固定数据库的连接对象 如下: 创建一个连接池管理类ConnPool
(1).定义数据库驱动类的路径, 数据库的访问地址及用户名和密码
图1
(2).在类中添加静态块, 程序在刚启动时先自动执行静态块,创建maxCon 个连接对象放入连接池中(即list 集合中
);
图2
(3) 定义一个获取连接对象的方法
图3
Synchronized 关键字表示同步, 意思是如果某个用户正在调用这个方法, 那么必须等待这个用户执行完这个方法后, 你才能调用这个方法
conList.size()-1 集合中最后一元素的索引 也说是取集合中最后 一个连接对象
(4) 定义一个关闭连接对象的方法
思考: 为什么不取集合中的第一个元素 conList.remove( 0) ?
图4
为了能灵活的操作不同的数据库,可通过资源文件来实现
息. 即在资源文件中设置驱动类路径Driver , 连接字符串Url 地址等, 然后在程序中读资源文件的信
第二种: 通过读取资源文件driver 和url 创建 数据库连接对象
好处是方便程序的维护, 之后只需要修改资源文件的内容, 立即就能更
换数据库
(1) 先定义资源文件 dbInfo.txt
该文件必须放在项目中连接池管理类ConnPool 类同一个包中
内容如下
driver=com.microsoft.sqlserver.jdbc.SQLServerDriver //sqlserver的驱动类路径 url=jdbc:sqlserver://localhost:1433;DataBaseName=Demo //sqlserver连接数据库的地址 user=sa //用户名
pwd=sa //密码
maxPoolSize=10 //连接池中连接对象的数量
(2) 创建一个连接池管理类ConnPool
在连接池类中定义以下变量
(a) 定义一个读取资源文件的方法
注: pro.getProperty(“driver ”) ;括号中名字与资源文件中等号前面的名称一致 如: driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
(b)在类中添加静态块, 调用读资源文件的方法, 并创建指定数量的连接对象放入连接池
(c)定义一个获得连接对象的方法 同图3
(d)定义一个关闭连接对象的方法 同图4