04. 数据库连接池(DataSource)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据库连接池(DataSource)

1、概念

在三层架构中,DAO层直接与数据库交互,首先要建立与数据库的连接,如果采用下图(a)所示,则用户每次的请求都要创建连接,用完又关闭,而数据库连接的创建和关闭需要消耗较大的资源,因此实际开发中常采用图(b)所示,在应用程序启动时创建一个包含多个Connection对象的连接池,DAO层使用时直接从池子里取一个Connection对象,用完后放回池子,避免了重复创建关闭数据库连接造成的开销。

2、数据库连接池原理

下面的代码模拟了数据库连接池的原理(代码中的JDBCUtil工具类见《MySQL(JDBC)》),池子里保持了10个Connection对象,并提供了getConnection和release方法:

public class ConnectionPoolDemo {

//连接池实际上就是一个List

private static List pool = new LinkedList();

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 List pool;//close方法中需要用

//3、在构造方法中传入被包装类的实例

public MyConnection(Connection conn,List pool){ this.conn = conn;

this.pool = pool;

}

//4、对于需要改写的方法,编写自己的代码即可

public void close() throws SQLException {

pool.add(conn);

}

//5、对于不需要改写的方法,调用被包装对象的对应方法

public T unwrap(Class iface) throws SQLException {

return conn.unwrap(iface);

}

……//其他代码从略

}

②实现DataSource接口。

public class MyDataSource implements DataSource {

private static List pool = new LinkedList();

static{

try {

for(int i=0;i<10;i++){

Connection conn = JDBCUtil.getConnection();//创建的新连接

pool.add(conn);

}

} catch (Exception e) {

e.printStackTrace();

}

}

public Connection getConnection() throws SQLException {

相关文档
最新文档