现在的位置: 首页 > 综合 > 正文

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

2013年08月20日 ⁄ 综合 ⁄ 共 13298字 ⁄ 字号 评论关闭
最近,本人着手开发要有一个有强大后台的网站,在使用连接池时,觉得使用服务器自带的连接池总有些受限制。同时,为了加深对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.minConnthis.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(i1){
????????????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????????????cc=-cc;
????????????log("End?One?Part/r/n");
????????????log("run--增加连接?保持要求的最小连接数");?
????????????for(i=0;i????????????????newConnection();
????????????}
????????}
????????//增加连接?保持至少有一个可用连接
????????if(freeConns.size()????????????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);
????}

}

抱歉!评论已关闭.