自己写的数据库连接池(一)

最近,本人着手开发要有一个有强大后台的网站,在使用连接池时,觉得使用服务器自带的连接池总有些受限制。同时,为了加深对Java的学习和研究。写下了下面的连接池类。
该连接池主要有一下功能;
1)初始化一次,到处使用。
2)强大的日志功能,记录每一个sql动作,包括Connection、ResultSet?和Statement
3)根据连接的数量,定时自动回收已经释放或超时的连接。
4)配置灵活,可以使用各种JDBC驱动程序,支持多驱动程序。

源代码:


/*
*??@Title??连接池
*??@Author:?zxg
*??@Version?1.0
*??@Memo:定义数据库连接及其数据库连接池等
*/

package?com.drsl.db;



import?java.io.*;
import?java.sql.*;
import?java.util.*;
import?java.util.Date;
import?java.lang.reflect.*;
import?com.mysql.jdbc.Driver;

import?com.drsl.db.*;

public? class?ConnectionManager?{
????
???? static? private?ConnectionManager?instance;? //?唯一实例
???? static? private? int?clients;
???? static? private? int?maxonlinetime=30*60*1000;
????
???? private?Vector?drivers?=? new?Vector();
???? private?Hashtable?pools?=? new?Hashtable();
???? private?Timer?checkConnTimer= new?Timer();
????
???? static? private?PrintWriter?log;
???? /**
????*?返回唯一实例.如果是第一次调用此方法,则创建实例
????*
????*?@return?ConnectionManager?唯一实例
????*/

???? static? synchronized? public?ConnectionManager?getInstance()?{
???????? if?(instance?==?null)?{
????????????instance?=? new?ConnectionManager();
????????}
//????????clients++;
???????? return?instance;
????}
????
???? /**
????*?建构函数私有以防止其它对象创建本类实例
????*/

???? private?ConnectionManager()?{
????????init();
????}
????
???? /**
????*?读取属性完成初始化
????*/

???? private? void?init()?{
????????
???????? try?{
????????????
????????????InputStream????is?=??getClass().getResourceAsStream( "db.properties");
????????????
????????????Properties????dbProps?=? new?Properties();
????????
????????????dbProps.load(is);
????????}
???????? catch?(Exception?e)?{
????????????e.printStackTrace();
????????????System.err.println( "不能读取属性文件=?"?+
???????????? "请确保db.properties在CLASSPATH指定的路径中");
???????????? return;
????????}
????????String?logFile?=?dbProps.getProperty( "logfile",? "log.txt");
???????? try?{
????????????log?=? new?PrintWriter( new?FileWriter(logFile,? true),? true);
????????}
???????? catch?(IOException?e)?{
????????????System.err.println( "无法打开日志文件:?"?+?logFile);
????????????log?=? new?PrintWriter(System.err);
????????}
????????loadDrivers(dbProps);
????????createPools(dbProps);
????}
????
???? /**
????*?装载和注册所有JDBC驱动程序
????*
????*?@param?props?属性
????*/

???? private? void?loadDrivers(Properties?props)?{
????????String?driverClasses?=?props.getProperty( "drivers");
????????StringTokenizer?st?=? new?StringTokenizer(driverClasses);
???????? while?(st.hasMoreElements())?{
????????????String?driverClassName?=?st.nextToken().trim();
???????????? try?{
????????????????
????????????????Driver?driver?=?(Driver)Class.forName(driverClassName).newInstance();
???????????????? if(driver!=null){
????????????????????DriverManager.registerDriver(driver);
????????????????????drivers.addElement(driver);
????????????????????log( "Begin");
????????????????????log( "成功注册JDBC驱动程序"?+?driverClassName);
????????????????}
???????????????? else{
????????????????????log( "Begin");
????????????????????log( "注册JDBC驱动程序"?+?driverClassName+ "失败");
????????????????}
????????????????????
????????????}
???????????? catch?(Exception?e)?{
????????????????log( "Begin");
????????????????log( "无法注册JDBC驱动程序:?"?+?driverClassName?+? ",?错误:?"?+?e);
????????????}
????????}
????}
????
???? /**
????*?根据指定属性创建连接池实例.
????*
????*?@param?props?连接池属性
????*/

???? private? void?createPools(Properties?props)?{
????????
????????Enumeration?propNames?=?props.propertyNames();
???????? while?(propNames.hasMoreElements())?{
????????????String?name?=?(String)?propNames.nextElement();
???????????? if?(name.endsWith( ".url"))?{
????????????????String?poolName?=?name.substring(0,?name.lastIndexOf( "."));
????????????????String?url?=?props.getProperty(poolName?+? ".url");
???????????????? if?(url?==?null)?{
????????????????????log( "没有为连接池"?+?poolName?+? "指定URL");
???????????????????? continue;
????????????????}
????????????????
????????????????String?user?=?props.getProperty(poolName?+? ".user");
????????????????String?password?=?props.getProperty(poolName?+? ".password");
????????????????
????????????????String?maxconn?=?props.getProperty(poolName?+? ".maxconn",? "0");
????????????????String?minconn?=?props.getProperty(poolName?+? ".minconn",? "10");
????????????????String?option=props.getProperty(poolName+ ".option", "");
???????????????? int?max,min;
???????????????? try?{
????????????????????max?=?Integer.valueOf(maxconn).intValue();
????????????????????
????????????????}
???????????????? catch?(NumberFormatException?e)?{
????????????????????log( "错误的最大连接数限制:?"?+?maxconn?+? "?.连接池:?"?+?poolName);
????????????????????max?=?0;
????????????????}
????????????????
???????????????? try?{
????????????????????min?=?Integer.valueOf(minconn).intValue();
????????????????????
????????????????}
???????????????? catch?(NumberFormatException?e)?{
????????????????????log( "错误的最小连接数限制:?"?+?minconn?+? "?.连接池:?"?+?poolName);
????????????????????min?=?0;
????????????????}
????????????????
???????????????? try{
????????????????????ConnectionPool?pool?=? new?ConnectionPool(poolName,?url,user,password,min,max,option);
????????????????????
????????????????????pools.put(poolName,?pool);
????????????????????
???????????????????? //2秒钟后开始每个一分钟检查一次连接池情况
????????????????????checkConnTimer.schedule(pool,2000,60*1000);

????????????????????log( "成功创建连接池"?+?poolName);
????????????????????
????????????????} catch(Exception?e){
????????????????????log(e, "创建DBConnectionPool出错");
????????????????}
????????????}
????????}
????}

???? /**
????*?将连接对象返回给由名字指定的连接池
????*
????*?@param?name?在属性文件中定义的连接池名字
????*?@param?con?连接对象
????*/

???? public? void?freeConnection(String?name,?Connection?conn)?{
????????ConnectionPool?pool?=?(ConnectionPool)?pools.get(name);
???????? if?(pool?!=?null)?{
????????????pool.freeConnection(conn);
????????}
????}
????
???? /**
????*?获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
????*?限制,则创建并返回新连接
????*
????*?@param?name?在属性文件中定义的连接池名字
????*?@return?Connection?可用连接或null
????*/

???? public?Connection?getConnection(String?name)?{
????????ConnectionPool?pool?=?(ConnectionPool)?pools.get(name);
???????? if?(pool?!=?null)?{
???????????? return?pool.getConnection();
????????}
???????? return?null;
????}
????
???? /**
????*?获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
????*?则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
????*
????*?@param?name?连接池名字
????*?@param?time?以毫秒计的等待时间
????*?@return?Connection?可用连接或null
????*/

???? public?Connection?getConnection(String?name,? long?time)?{
????????ConnectionPool?pool?=?(ConnectionPool)?pools.get(name);
???????? if?(pool?!=?null)?{
???????????? return?pool.getConnection(time);
????????}
???????? return?null;
????}
????
???? /**
????*?关闭所有连接,撤销驱动程序的注册
????*/

???? public? synchronized? void?release()?{
???? //?等待直到最后一个客户程序调用
//????????if?(--clients?!=?0)?{
//????????????return;
//????????}
????????
????????checkConnTimer.cancel();
????????
????????Enumeration?allPools?=?pools.elements();
???????? while?(allPools.hasMoreElements())?{
????????????ConnectionPool?pool?=?(ConnectionPool)?allPools.nextElement();
????????????pool.cancel();
????????????pool.release();
????????}
????????Enumeration?allDrivers?=?drivers.elements();
???????? while?(allDrivers.hasMoreElements())?{
????????????Driver?driver?=?(Driver)?allDrivers.nextElement();
???????????? try?{
????????????????DriverManager.deregisterDriver(driver);
????????????????log( "撤销JDBC驱动程序?"?+?driver.getClass().getName()+ "的注册");
????????????}
???????????? catch?(SQLException?e)?{
????????????????log(e, "无法撤销下列JDBC驱动程序的注册:?"?+?driver.getClass().getName());
????????????}
????????}

????}
????
???? /**
????*?将文本信息写入日志文件
????*/

???? static? public? void?log(String?msg)?{
????????log.println( new?Date()?+? ":?"?+?msg);
????}
????
???? /**
????*?将文本信息与异常写入日志文件
????*/

???? static? public? void?log(Throwable?e,?String?msg)?{
????????log.println( new?Date()?+? ":?"?+?msg);
????????e.printStackTrace(log);
????}
//测试

????????
???? static? public? void?main(String[]?args)?{
????????
????????ConnectionManager?dcm=null;
????????
???????? try{
????????????dcm=ConnectionManager.getInstance();
????????????
????????????Connection?conn=dcm.getConnection( "mysql");
????????????Connection?conn1=dcm.getConnection( "mysql");
????????????Connection?conn2=dcm.getConnection( "mysql");
????????????Connection?conn3=dcm.getConnection( "mysql");
????????????Connection?conn4=dcm.getConnection( "mysql");
????????????Connection?conn5=dcm.getConnection( "mysql");
????????????Connection?conn6=dcm.getConnection( "mysql");
????????????Connection?conn7=dcm.getConnection( "mysql");
????????????Connection?conn8=dcm.getConnection( "mysql");
????????????Connection?conn9=dcm.getConnection( "mysql");
????????????Connection?conn10=dcm.getConnection( "mysql");
????????????Connection?conn11=dcm.getConnection( "mysql");
????????????Connection?conn12=dcm.getConnection( "mysql");
????????????Connection?conn13=dcm.getConnection( "mysql");
????????????Connection?conn14=dcm.getConnection( "mysql");
????????????
????????????ResultSet?rs;
????????????
????????????String?sql= "select?*?from?css";
????????
????????????Statement?st=conn.createStatement();
???????????? if(st==null)?{
????????????????log( "main--error?while?get?/"Statement/"");
???????????????? return;
????????????}
????????????rs=st.executeQuery(sql);
???????????? if(rs==null){
????????????????log( "main--error?while?get?/"ResultSet/"");
???????????????? return;
????????????}
????????????System.out.println( "/r/n");
????????????????????????
???????????? while(rs.next()){
????????????????System.out.println(rs.getString(1));
????????????}
????????????rs.close();
????????????st.close();
????????????rs=null;
????????????st=null;
????????????
????????????
????????????conn.close();
????????????conn1.close();
????????????conn2.close();
????????????conn3.close();
????????????conn4.close();
????????????conn5.close();
????????????conn6.close();
????????????conn7.close();
????????????conn8.close();
????????????conn9.close();
????????????conn10.close();
????????????conn11.close();
????????????conn12.close();
????????????conn13.close();
????????????conn14.close();
????????????
????????????conn=null;
????????????conn1=null;
????????????conn2=null;
????????????conn3=null;
????????????conn4=null;
????????????conn5=null;
????????????conn6=null;
????????????conn7=null;
????????????conn8=null;
????????????conn9=null;
????????????conn10=null;
????????????conn11=null;
????????????conn12=null;
????????????conn13=null;
????????????conn14=null;
????????????
????????} catch(SQLException?e){
????????????dcm.log(e, "main--error");
????????}
????}

}

//



/***************连接池类*************************************************/

/**
*?此类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
*?大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*?它继承自?TimerTask?被?ConnectionManager?类的timer成员调度
*/

package?com.drsl.db;

import?java.io.*;
import?java.sql.*;
import?java.util.*;
import?java.util.Date;
import?java.lang.reflect.*;

import?com.drsl.db.*;

public? class?ConnectionPool? extends?TimerTask{
????
???? private? int?countConn;
????
???? private?Vector?freeConns?=? new?Vector();
???? private?Vector?usingConns?=? new?Vector();
????
???? private? int?maxUseTime; //使用中的连接最大空闲时间
???? private? int?maxFreeTime; //空闲的连接最大空闲时间(在连接数未小于最小连接数时,关闭此连接)
????
???? private? int?maxConn; //最大连接数
???? private? int?minConn; //最小连接数
????
???? private?String?name; //pool?name
???? private?String?url;
???? private?String?user;
???? private?String?password;
???? private?String?option;
????
//????private?PrintWriter?log;

???? /**
????*?创建新的连接池
????*
????*?@param?name?连接池名字
????*?@param?url?数据库的JDBC?url
????*?@param?dbInfo?数据库连接信息
????*?@param?maxConn?此连接池允许建立的最大连接数
????*/

???? public?ConnectionPool(String?name,?String?url,String?user,String?password,? int?minConn, int?maxConn,String?option)?{
???????? this.name?=?name;
???????? this.url?=?url;
???????? this.user?=?user;
???????? this.password?=?password;
???????? this.option=option;
????????
???????? this.maxConn?=?maxConn;
???????? this.minConn?=?minConn;
????????
???????? if( this.minConn<=0)? this.minConn=10;
????????
????????log( "End?One?Part/r/n");
???????? for( int?i=0;?i
????????????newConnection();?
????????}
????}
???? /**
????*?将新建的连接添加到连接池
????*
????*?@param?connobj?新建的连接
????*/

???? public? synchronized? void?freeConnection(ConnectionObject?connobj)?{
???????? //?将指定连接加入到向量末尾
???????? try{
????????????connobj.setInUse( false);
????????????freeConns.addElement(connobj);
????????????log( "成功记录一个新建连接或者回收一个已释放连接");
????????????notifyAll();
????????} catch(ArrayIndexOutOfBoundsException?e){
????????????log(e, "freeConnection(ConnectionObject?connobj)?--失败");
????????????
????????}
????}
???? /**
????*?将不再使用的连接返回给连接池
????*
????*?@param?conn?客户程序主动释放的连接
????*/

???? public? synchronized? void?freeConnection(Connection?conn)?{
???????? //?将指定连接加入到向量末尾
????????ConnectionObject?connobj=null;
????????
???????? for( int?i=0;i
????????{
????????????connobj=(ConnectionObject)usingConns.get(i);
????????????
???????????? if(connobj.getConnection()==conn)
???????????????? break;
????????}
???????? if(connobj!=null){
???????????? try{
????????????????connobj.setInUse( false);
????????????????freeConns.addElement(connobj);
????????????????usingConns.removeElement(connobj);
????????????????log( "成功回收一个连接");
????????????????notifyAll();
????????????} catch(Exception?e){
????????????????log(e, "回收一个连接--失败");
????????????}
????????}
????}
????
???? /**
????*?从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
????*?数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
????*?然后递归调用自己以尝试新的可用连接.
????*/

???? public? synchronized?Connection?getConnection()?{
????????ConnectionObject?connobj?=?null;
????????Connection?conn=null;
???????? //?获取向量中第一个可用连接
???????? try?{
????????????connobj?=?(ConnectionObject)?freeConns.get(0);
????????}
???????? catch?(Exception?e)?{
????????????
????????????log( "End?One?Part/r/n");

????????????log( "从连接池"?+?name+ "获取一个连接失败");
???????????? if(?maxConn?==?0?||?countConn? ????????????????connobj?=?newConnection();
????????????}
????????}
???????? //如没有空闲的连接且当前连接数小于最大连接数限制,则创建新连接
???????? if(connobj==null?&&?(?maxConn?==?0?||?countConn? ????????????log( "从连接池"?+?name+ "获取一个连接失败");
????????????log( "End?One?Part/r/n");
????????????connobj?=?newConnection();
????????}
???????? if?(connobj?!=?null)?{
????????????
????????????connobj.setLastAccessTime( new?Date().getTime());
????????????connobj.setInUse( true);
????????????
????????????usingConns.addElement(connobj);
????????????freeConns.removeElementAt(0);
????????????
????????????conn=connobj.getConnection();
???????????? return?conn;
????????????
????????} else{
????????????log( "获取连接"?+?name+ "失败--连接数量已达最大上限");
???????????? return?null;
????????}
????}
????
???? /**
????*?从连接池获取可用连接.可以指定客户程序能够等待的最长时间
????*?参见前一个getConnection()方法.
????*
????*?@param?timeout?以毫秒计的等待时间限制
????*/

???? public? synchronized?Connection?getConnection( long?timeout)?{
????????
???????? long?startTime?=? new?Date().getTime();
????????Connection?conn=null;
???????? while?((conn?=?getConnection())?==?null)?{
???????????? try?{
????????????????wait(timeout); //??????????????
????????????}
???????????? catch?(InterruptedException?e){
????????????????
????????????}
???????????? if?(( new?Date().getTime()?-?startTime)?>=?timeout)?{
???????????????? //?wait()返回的原因是超时?????????
???????????????? return?null;
????????????}
????????}
???????? return?conn;
????}
????
???? /**
????*?关闭所有连接
????*/

???? public? synchronized? void?release()?{
//????????cancel();
????????Enumeration?allConnections?=?freeConns.elements();
????????
???????? while?(allConnections.hasMoreElements())?{
????????????ConnectionObject?connobj?=?(ConnectionObject)?allConnections.nextElement();
???????????? try?{
????????????????connobj.close();
????????????????connobj=null;
????????????????log( "关闭连接池"?+?name+ "中的一个连接");
????????????}
???????????? catch?(SQLException?e)?{ //SQLException
????????????????log(e,? "无法关闭连接池"?+?name+ "中的连接");
????????????}
????????}
????????freeConns.removeAllElements();
???????? //
????????allConnections?=?usingConns.elements();
????????
???????? while?(allConnections.hasMoreElements())?{
????????????ConnectionObject?connobj?=?(ConnectionObject)?allConnections.nextElement();
???????????? try?{
????????????????connobj.close();
????????????????connobj=null;
????????????????log( "关闭连接池"?+?name+ "中的一个连接");
????????????}
???????????? catch?(SQLException?e)?{ //SQLException
????????????????log(e,? "无法关闭连接池"?+?name+ "中的连接");
????????????}
????????}
????????usingConns.removeAllElements();
????}
????
???? /**
????*?创建新的连接
????*/

???? private?ConnectionObject?newConnection()?{
????????ConnectionObject?connobj=?null;?
???????? try?{
????????????
????????????log( "连接池"?+?name+ "创建一个新的连接对象");
?????????????
????????????String?URL=url+option;
????????????
?????????????log( "URL="?+URL?);
?????????????
?????????????Connection?conn?=?DriverManager.getConnection(URL,user,password);
????????????
????????????connobj= new?ConnectionObject(conn, false);
????????????
????????????freeConnection(connobj);
????????????countConn++;
????????????
????????}?
???????? catch?(SQLException?e)?{?
????????????log(e,? "无法创建下列URL的连接:?"?+?url+ "?for?User=?"?+user+ "?Password="+password);?
???????????? return?null;?
????????}?
???????? return?connobj;?
????}?
???? //检查各连接状态(每分钟一次)
???? public? void?run?(){
????????
????????ConnectionObject?connobj=null;
???????? //回收?正在使用中的已经"关闭"的连接????
???????? //和?使用时间已经超时的连接
???????? int?i=0;????
???????? while(i

?????????????connobj=(ConnectionObject)usingConns.get(i);
???????????? if(connobj.isInUse()== false){
???????????????? try{
????????????????????????log( "run--回收?正在使用中的已经/"关闭/"的连接");?
????????????????????????freeConnection(connobj);
????????????????????????usingConns.removeElementAt(i);????????
????????????????????????i--;
????????????????} catch(ArrayIndexOutOfBoundsException?e){
????????????????????log(e, "run--回收?正在使用中的已经/"关闭/"的连接--失败");?
????????????????}
????????????} else{
????????????
???????????????? long?nowtime= new?Date().getTime();
???????????????? long?t=nowtime-connobj.getLastAccessTime();
???????????????? try{
???????????????????? if(t>20*60*1000){ //超时时间为20分钟
????????????????????????log( "run--回收?使用时间已经超时的连接");?
????????????????????????freeConnection(connobj);
????????????????????????usingConns.removeElementAt(i);
????????????????????????i--;
????????????????????}
????????????????} catch(ArrayIndexOutOfBoundsException?e?){
????????????????????log(e, "run--回收?使用时间已经超时的连接--失败");?
????????????????}
????????????}
????????????i++;
????????}
???????? //删除?空闲的已经被意外关闭的连接
????????i=0;
???????? while(i
????????
????????????connobj=?(ConnectionObject)freeConns.get(i);
???????????? try{
???????????????? if(connobj.getConnection().isClosed()){
????????????????????connobj=null;
????????????????????freeConns.removeElementAt(i);
????????????????????countConn--;
????????????????????i--;
????????????????????log( "run--删除?空闲的已经被意外关闭的连接");?
????????????????}
????????????} catch(Exception?e){
????????????????log(e, "run--删除?空闲的已经被意外关闭的连接-失败");?
????????????}
????????????i++;
????????}
????????
???????? //删除?从空闲连接中多余的(大于最小连接数的)连接?
???????? long?cc=countConn-minConn;
????????i=0;
???????? while(i 1){
???????????? try{
????????????????connobj=(ConnectionObject)freeConns.get(0);
????????????????connobj.close();
????????????????connobj=null;
????????????????freeConns.removeElementAt(0);
????????????????countConn--;
????????????????log( "run--删除?从空闲连接中多余的(大于最小连接数的)连接?");?
????????????} catch(SQLException?e){
????????????????log(e, "run--从空闲连接中多余的(大于最小连接数的)连接--失败");?
????????????}
????????????i++;
????????}
???????? //增加连接?保持要求的最小连接数
???????? if(cc<0){
????????????cc=-cc;
????????????log( "End?One?Part/r/n");
????????????log( "run--增加连接?保持要求的最小连接数");?
???????????? for(i=0;i
????????????????newConnection();
????????????}
????????}
???????? //增加连接?保持至少有一个可用连接
???????? if(freeConns.size()<1){
????????????log( "End?One?Part/r/n");
????????????log( "run--增加连接?保持至少有一个可用连接");?
????????????newConnection();
????????}
????????log( "run--once");
???? //????notifyAll();
????}
???? /**
????*?将文本信息写入日志文件
????*/

???? private? void?log(String?msg)?{
????????ConnectionManager.log(msg);
????}
????
???? /**
????*?将文本信息与异常写入日志文件
????*/

???? private? void?log(Throwable?e,?String?msg)?{
????????ConnectionManager.log(e,msg);
????}
????????

}


/

/**
?*?数据连接的自封装,屏蔽了close方法和createStatement,prepareStatement?方法以返回自己的接管类
?*?@author?zxg
?*/

package?com.drsl.db;

import?java.io.*;
import?java.sql.*;
import?java.util.*;
import?java.util.Date;
import?java.lang.reflect.*;

public? class?ConnectionObject? implements?InvocationHandler{
????
???? private? final? static?String?CLOSE_METHOD_NAME?=? "close";
???? private? final? static?String?CREATSTATMENT_METHOD_NAME?=? "createStatement";
???? private? final? static?String?PREPARESTATEMENT_METHOD_NAME?=? "prepareStatement";
????
???? private?Connection?conn?=?null;
???? private????Connection?conn_proxy=null;
???? private?PreparedStatementObject?pso=null;
???? private?StatementObject?stmo=null;
????
???? //数据库的忙状态
???? private? boolean?inUse?=? false;
????
???? //用户最后一次访问该连接方法的时间
???? private? static? long?lastAccessTime?=? new?Date().getTime();


???? public?ConnectionObject(Connection?conn,? boolean?inUse){
???????? this.conn?=?conn;
???????? this.inUse?=?inUse;
????}
????
???? /**
?????*?Returns?the?conn.
?????*?@return?Connection
?????*/

???? //返回数据库连接conn的接管类,以便截住Connection?的各个方法
???? public?Connection?getConnection()?{
???????? if(conn_proxy==null){
????????????ClassLoader?classloader=conn.getClass().getClassLoader();
????????????Class[]?interfaces?=?conn.getClass().getInterfaces();?
????????????
???????????? if(interfaces==null||interfaces.length==0){?
????????????????interfaces?=? new?Class[1];?
????????????????interfaces[0]?=?Connection. class;?
????????????}
????????????
???????????? try{
????????????????
????????????????conn_proxy=?(Connection)Proxy.newProxyInstance(classloader,interfaces, this);
????????????????
????????????} catch(NullPointerException?e){
????????????????log(e, "ConnectionObject?getConnection()--error");
????????????}
???????????? if(conn_proxy!=null)
????????????????log( "ConnectionObject?getConnection()--success");
????????}
???????? return?conn_proxy;
????}
????
???? /**
?????*?该方法真正的关闭了数据库的连接
?????*?@throws?SQLException
?????*/

???? synchronized? void??close()? throws?SQLException{
???????? //由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
????????conn.close();
????????conn=null;
????}
???? /**
?????*?Returns?the?inUse.
?????*?@return?boolean
?????*/

???? public? boolean?isInUse()?{
???????? return?inUse;
????}

???? /**
?????*?@see?java.lang.reflect.InvocationHandler#invoke(java.lang.Object,?java.lang.reflect.Method,?java.lang.Object)
?????*/

???? public?Object?invoke(Object?proxy,?Method?m,?Object[]?args)?
???????? throws?Throwable?
????{
????????Object?obj?=?null;
????????log( "ConnectionObject--invoke:Method:?/""+m.getName()+ "/"");
????????
???????? //判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
????????
???????? if(CLOSE_METHOD_NAME.equals(m.getName())){
????????????setInUse( false);
????????????????????
????????} else? if(CREATSTATMENT_METHOD_NAME.equals(m.getName())){
????????????
???????? //如果调用了?createStatment?的方法,封装?Statement?类接受管理
????????
????????????Statement?stm=(Statement)?m.invoke(conn,?args);
???????????? if(stm!=null?&&?stmo==null){
????????????????stmo= new?StatementObject(stm);
????????????????obj=stmo.getStatement();
????????????} else{
????????????????ConnectionManager.log( "ConnectionObject--invoke:Method:?/""+m.getName()+ "/"--失败");
????????????}
????????????
????????} else? if(PREPARESTATEMENT_METHOD_NAME.equals(m.getName())){
????????????
???????? //如果调用了?createStatment?的方法,封装?PreparedStatement?类接受管理
????????
????????????PreparedStatement?ps=(PreparedStatement)?m.invoke(conn,?args);
????????????
???????????? if(ps!=null?&&?pso==null){
????????????????pso= new?PreparedStatementObject(ps);
????????????}
???????????? else? if(pso!=null){
????????????????obj=pso.getPreparedStatement();
????????????} else
????????????????log( "ConnectionObject--invoke:Method:?/""+m.getName()+ "/"--失败");
????????????
????????} else
????????????obj?=?m.invoke(conn,?args);????
????????????
???????? //设置最后一次访问时间,以便及时清除超时的连接
????????lastAccessTime?=? new?Date().getTime();
???????? return?obj;
????}
????????
???? /**
?????*?Returns?the?lastAccessTime.
?????*?@return?long
?????*/

???? public? static? long?getLastAccessTime()?{
???????? return?lastAccessTime;
????}
???? /**
?????*?set?the?lastAccessTime.
?????*?@param?latimelong
?????*/

????
???? public? static? void?setLastAccessTime( long?latime)?{
????????lastAccessTime=latime;
????}

???? /**
?????*?Sets?the?inUse.
?????*?@param?inUse?The?inUse?to?set
?????*/

???? public? void?setInUse( boolean?inUse)?{
???????? this.inUse?=?inUse;
????}
????
???? public? synchronized? void?release()?{
???????? try{
????????????close();
????????} catch(SQLException?e){
????????????log(e, "ConnectionObject--release?调用?close?失败");
????????}
????}
???????? /**
????*?将文本信息写入日志文件
????*/

???? private? void?log(String?msg)?{
????????ConnectionManager.log(msg);
????}
????
???? /**
????*?将文本信息与异常写入日志文件
????*/

???? private? void?log(Throwable?e,?String?msg)?{
????????ConnectionManager.log(e,msg);
????}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值