其次是连接池的工厂类connectionfactory,通过该类来将一个连接池对象与一个名称对应起来,使用者通过该名称就可以获取指定的连接池对象,具体代码如下:
/**
* 连接池类厂,该类常用来保存多个数据源名称合数据库连接池对应的哈希
* @author liusoft
*/
public class connectionfactory
{
//该哈希表用来保存数据源名和连接池对象的关系表
static hashtable connectionpools = null;
static{
connectionpools = new hashtable(2,0.75f);
}
/**
* 从连接池工厂中获取指定名称对应的连接池对象
* @param datasource 连接池对象对应的名称
* @return datasource 返回名称对应的连接池对象
* @throws namenotfoundexception 无法找到指定的连接池
*/
public static datasource lookup(string datasource)
throws namenotfoundexception
{
object ds = null;
ds = connectionpools.get(datasource);
if(ds == null || !(ds instanceof datasource))
throw new namenotfoundexception(datasource);
return (datasource)ds;
}
/**
* 将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池
* @param name 对应连接池的名称
* @param param 连接池的配置参数,具体请见类connectionparam
* @return datasource 如果绑定成功后返回连接池对象
* @throws namealreadyboundexception 一定名字name已经绑定则抛出该异常
* @throws classnotfoundexception 无法找到连接池的配置中的驱动程序类
* @throws illegalaccessexception 连接池配置中的驱动程序类有误
* @throws instantiationexception 无法实例化驱动程序类
* @throws sqlexception 无法正常连接指定的数据库
*/
public static datasource bind(string name, connectionparam param)
throws namealreadyboundexception,classnotfoundexception,
illegalaccessexception,instantiationexception,sqlexception
{
datasourceimpl source = null;
try{
lookup(name);
throw new namealreadyboundexception(name);
}catch(namenotfoundexception e){
source = new datasourceimpl(param);
source.initconnection();
connectionpools.put(name, source);
}
return source;
}
/**
* 重新绑定数据库连接池
* @param name 对应连接池的名称
* @param param 连接池的配置参数,具体请见类connectionparam
* @return datasource 如果绑定成功后返回连接池对象
* @throws namealreadyboundexception 一定名字name已经绑定则抛出该异常
* @throws classnotfoundexception 无法找到连接池的配置中的驱动程序类
* @throws illegalaccessexception 连接池配置中的驱动程序类有误
* @throws instantiationexception 无法实例化驱动程序类
* @throws sqlexception 无法正常连接指定的数据库
*/
public static datasource rebind(string name, connectionparam param)
throws namealreadyboundexception,classnotfoundexception,
illegalaccessexception,instantiationexception,sqlexception
{
try{
unbind(name);
}catch(exception e){}
return bind(name, param);
}
/**
* 删除一个数据库连接池对象
* @param name
* @throws namenotfoundexception
*/
public static void unbind(string name) throws namenotfoundexception
{
datasource datasource = lookup(name);
if(datasource instanceof datasourceimpl){
datasourceimpl dsi = (datasourceimpl)datasource;
try{
dsi.stop();
dsi.close();
}catch(exception e){
}finally{
dsi = null;
}
}
connectionpools.remove(name);
}
}
connectionfactory主要提供了用户将将连接池绑定到一个具体的名称上以及取消绑定的操作。使用者只需要关心这两个类即可使用数据库连接池的功能。下面我们给出一段如何使用连接池的代码:
string name = "pool";
string driver = " sun.jdbc.odbc.jdbcodbcdriver ";
string url = "jdbc:odbc:datasource";
connectionparam param = new connectionparam(driver,url,null,null);
param.setminconnection(1);
param.setmaxconnection(5);
param.settimeoutvalue(20000);
connectionfactory.bind(name, param);
system.out.println("bind datasource ok.");
//以上代码是用来登记一个连接池对象,该操作可以在程序初始化只做一次即可
//以下开始就是使用者真正需要写的代码
datasource ds = connectionfactory.lookup(name);
try{
for(int i=0;i<10;i++){
connection conn = ds.getconnection();
try{
testsql(conn, sql);
}finally{
try{
conn.close();
}catch(exception e){}
}
}
}catch(exception e){
e.printstacktrace();
}finally{
connectionfactory.unbind(name);
system.out.println("unbind datasource ok.");
system.exit(0);
}
从使用者的示例代码就可以看出,我们已经解决了常规连接池产生的两个问题。但是我们最最关心的是如何解决接管close方法的办法。接管工作主要在connectionfactory中的两句代码:
source = new datasourceimpl(param);
source.initconnection();
