- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
04数据库连接池(DataSource)
数据库连接池(DataSource)
1、概念
在三层架构中,DAO层直接与数据库交互,首先要建立与数据库的连接,如果采用下图(a)所示,则用户每次的请求都要创建连接,用完又关闭,而数据库连接的创建和关闭需要消耗较大的资源,因此实际开发中常采用图(b)所示,在应用程序启动时创建一个包含多个Connection对象的连接池,DAO层使用时直接从池子里取一个Connection对象,用完后放回池子,避免了重复创建关闭数据库连接造成的开销。
2、数据库连接池原理
下面的代码模拟了数据库连接池的原理(代码中的JDBCUtil工具类见《MySQL(JDBC)》),池子里保持了10个Connection对象,并提供了getConnection和release方法:
public class ConnectionPoolDemo {
//连接池实际上就是一个List
private static ListConnection pool = new LinkedListConnection();
static{//加载连接池类时在池子中放入10个连接
for(int i = 0;i 10;i ++){
Connection conn;
try {
conn = JDBCUtil.getConnection();
pool.add(conn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//从池子中取出一个连接
public synchronized Connection getConnection(){
return pool.remove(0);
}
//把连接还回池子中
public static void release(Connection conn){
pool.add(conn);
}
} 3、编写一个符合规范的连接池
上节模拟数据库连接池原理的代码也实现了一个简单连接池,但是不符合规范(Sun公司制定)。编写一个符合规范的连接池需要实现javax.sql.DataSource接口。(DataSource接口中定义了两个重载的getConnection方法)
编程难点 ☆:当用户使用完Connection,执行conn.close()时,Connection对象应保证将自己还给连接池,而不要把conn关闭。之所由Connection对象保证将自己返回到LinkedList中,是因为DataSource接口中并未定义上节例子中类似release的方法。所以必须改写Connection中的close方法,使得用户执行conn.close()时,将Connection对象还给连接池。
解决方案 ☆ :改写驱动程序中Connection类的close方法。对已知类的某些方法进行功能上的改变,有以下几种编码方案(☆):
1)编写子类,覆写需要改变的方法。此处行不通,原因有:① 程序中不知道继承哪个驱动的Connection实现类 ② 数据库驱动对Connection接口的实现类是final的,不允许被继承。
2)装饰(包装)设计模式(静态代理)
① 定义包装类:MyConnection,该类完成了对com.mysql.jdbc.Connection类的包装。
关键词:保持被包装对象的原有信息、对某个/某些方法进行改写。包装类的编写过程如下:
/**
* 目前要包装的类是:com.mysql.jdbc.Connection
* @author flyne
*/
//1、编写一个类,实现与被包装类相同的接口。
public class MyConnection implements Connection {
//2、定义一个变量,引用被包装类的实例(保持被包装对象的原有信息)
private Connection conn;
private ListConnection pool;//close方法中需要用
//3、在构造方法中传入被包装类的实例
public MyConnection(Connection conn,ListConnection pool){
this.conn = conn;
this.pool = pool;
}
//4、对于需要改写的方法,编写自己的代码即可
public void close() throws SQLException {
pool.add(conn);
}
//5、对于不需要改写的方法,调用被包装对象的对应方法
public T T unwrap(ClassT ifa
文档评论(0)