//是否连接池中的数据库连接的数量己经达到最大?
最大值由类成员maxConnections
//指出,如果maxConnections为0或负数,表示连接数量没有限制。
//如果连接数己经达到最大,即退出。
if(this.maxConnections>0&&this.connections.size()>=this.maxConnections){
break;
}
//addanewPooledConnectionobjecttoconnectionsvector
//增加一个连接到连接池中(向量connections中)
try{
connections.addElement(newPooledConnection(newConnection()));
}catch(SQLExceptione){
System.out.println("创建数据库连接失败!
"+e.getMessage());
thrownewSQLException();
}
System.out.println("数据库连接己创建......");
}
}
/**
*创建一个新的数据库连接并返回它
*
*@return返回一个新创建的数据库连接
*/
privateConnectionnewConnection()throwsSQLException{
//创建一个数据库连接
Connectionconn=DriverManager.getConnection(dbUrl,dbUsername,dbPassword);
//如果这是第一次创建数据库连接,即检查数据库,获得此数据库允许支持的
//最大客户连接数目
//connections.size()==0表示目前没有连接己被创建
if(connections.size()==0){
DatabaseMetaDatametaData=conn.getMetaData();
intdriverMaxConnections=metaData.getMaxConnections();
//数据库返回的driverMaxConnections若为0,表示此数据库没有最大
//连接限制,或数据库的最大连接限制不知道
//driverMaxConnections为返回的一个整数,表示此数据库允许客户连接的数目
//如果连接池中设置的最大连接数量大于数据库允许的连接数目,则置连接池的最大
//连接数目为数据库允许的最大数目
if(driverMaxConnections>0&&this.maxConnections>driverMaxConnections){
this.maxConnections=driverMaxConnections;
}
}
returnconn;//返回创建的新的数据库连接
}
/**
*通过调用getFreeConnection()函数返回一个可用的数据库连接,
*如果当前没有可用的数据库连接,并且更多的数据库连接不能创
*建(如连接池大小的限制),此函数等待一会再尝试获取。
*
*@return返回一个可用的数据库连接对象
*/
publicsynchronizedConnectiongetConnection()throwsSQLException{
//确保连接池己被创建
if(connections==null){
returnnull;//连接池还没创建,则返回null
}
Connectionconn=getFreeConnection();//获得一个可用的数据库连接
//如果目前没有可以使用的连接,即所有的连接都在使用中
while(conn==null){
//等一会再试
wait(250);
conn=getFreeConnection();//重新再试,直到获得可用的连接,如果
//getFreeConnection()返回的为null
//则表明创建一批连接后也不可获得可用连接
}
returnconn;//返回获得的可用的连接
}
/**
*本函数从连接池向量connections中返回一个可用的的数据库连接,如果
*当前没有可用的数据库连接,本函数则根据incrementalConnections设置
*的值创建几个数据库连接,并放入连接池中。
*如果创建后,所有的连接仍都在使用中,则返回null
*@return返回一个可用的数据库连接
*/
privateConnectiongetFreeConnection()throwsSQLException{
//从连接池中获得一个可用的数据库连接
Connectionconn=findFreeConnection();
if(conn==null){
//如果目前连接池中没有可用的连接
//创建一些连接
createConnections(incrementalConnections);
//重新从池中查找是否有可用连接
conn=findFreeConnection();
if(conn==null){
//如果创建连接后仍获得不到可用的连接,则返回null
returnnull;
}
}
returnconn;
}
/**
*查找连接池中所有的连接,查找一个可用的数据库连接,
*如果没有可用的连接,返回null
*
*@return返回一个可用的数据库连接
*/
privateConnectionfindFreeConnection()throwsSQLException{
Connectionconn=null;
PooledConnectionpConn=null;
//获得连接池向量中所有的对象
Enumerationenumerate=connections.elements();
//遍历所有的对象,看是否有可用的连接
while(enumerate.hasMoreElements()){
pConn=(PooledConnection)enumerate.nextElement();
if(!
pConn.isBusy()){
//如果此对象不忙,则获得它的数据库连接并把它设为忙
conn=pConn.getConnection();
pConn.setBusy(true);
//测试此连接是否可用
if(!
testConnection(conn)){
//如果此连接不可再用了,则创建一个新的连接,
//并替换此不可用的连接对象,如果创建失败,返回null
try{
conn=newConnection();
}catch(SQLExceptione){
System.out.println("创建数据库连接失败!
"+e.getMessage());
returnnull;
}
pConn.setConnection(conn);
}
break;//己经找到一个可用的连接,退出
}
}
returnconn;//返回找到到的可用连接
}
/**
*测试一个连接是否可用,如果不可用,关掉它并返回false
*否则可用返回true
*
*@paramconn需要测试的数据库连接
*@return返回true表示此连接可用,false表示不可用
*/
privatebooleantestConnection(Connectionconn){
try{
//判断测试表是否存在
if(testTable.equals("")){
//如果测试表为空,试着使用此连接的setAutoCommit()方法
//来判断连接否可用(此方法只在部分数据库可用,如果不可用,
//抛出异常)。
注意:
使用测试表的方法更可靠
conn.setAutoCommit(true);
}else{//有测试表的时候使用测试表测试
//checkifthisconnectionisvalid
Statementstmt=conn.createStatement();
stmt.execute("selectcount(*)from"+testTable);
}
}catch(SQLExceptione){
//上面抛出异常,此连接己不可用,关闭它,并返回false;
closeConnection(conn);
returnfalse;
}
//连接可用,返回true
returntrue;
}
/**
*此函数返回一个数据库连接到连接池中,并把此连接置为空闲。
*所有使用连接池获得的数据库连接均应在不使用此连接时返回它。
*
*@param需返回到连接池中的连接对象
*/
publicvoidreturnConnection(Connectionconn){
//确保连接池存在,如果连接没有创建(不存在),直接返回
if(connections==null){
System.out.println("连接池不存在,无法返回此连接到连接池中!
");
return;
}
PooledConnectionpConn=null;
Enumerationenumerate=connections.elements();
//遍历连接池中的所有连接,找到这个要返回的连接对象
while(enumerate.hasMoreElements()){
pConn=(PooledConnection)enumerate.nextElement();
//先找到连接池中的要返回的连接对象
if(conn==pConn.getConnection()){
//找到了,设置此连接为空闲状态
pConn.setBusy(false);
break;
}
}
}
/**
*刷新连接池中所有的连接对象
*
*/
publicsynchronizedvoidrefreshConnections()throwsSQLException{
//确保连接池己创新存在
if(connections==null){
System.out.println("连接池不存在,无法刷新!
");
return;
}
PooledConnectionpConn=null;
Enumerationenumerate=connections.elements();
while(enumerate.hasMoreElements()){
//获得一个连接对象
pConn=(PooledConnection)enumerate.nextElement();
//如果对象忙则等5秒,5秒后直接刷新
if(pConn.isBusy()){
wait(5000);//等5秒
}
//关闭此连接,用一个新的连接代替它。
closeConnection(pConn.getConnection());
pConn.setConnection(newConnection());
pConn.setBusy(false);
}
}
/**
*关闭连接池中所有的连接,并清空连接池。
*/
publicsynchronizedvoidcloseConnectionPool()throwsSQLException{
//确保连接池存在,如果不存在,返回
if(connections==null){
System.out.println("连接池不存在,无法关闭!
");
return;
}
PooledConnectionpConn=null;
Enumerationenumerate=connections.elements();
while(enumerate.hasMoreElements()){
pConn=(PooledConnection)enumerate.nextElement();
//如果忙,等5秒
if(pConn.isBusy()){
wait(5000);//等5秒
}
//5秒后直接关闭它
closeConnection(pConn.getConnection());
//从连接池向量中删除它
connections.removeElement(pConn);
}
//置连接池为空
connections=null;
}
/**
*关闭一个数据库连接
*
*@param需要关闭的数据库连接
*/
privatevoidcloseConnection(Connectionconn){
try{
conn.close();
}catch(SQLExceptione){
System.out.println("关闭数据库连接出错:
"+e.getMessage());
}
}
/**
*使程序等待给定的毫秒数
*
*@param给定的毫秒数
*/
privatevoidwait(intmSeconds){
try{
Thread.sleep(mSeconds);
}catch(InterruptedExceptione){
}
}
/**
*
*内部使用的用于保存连接池中连接对象的类
*此类中有两个成员,一个是数据库的连接,另一个是指示此连接是否
*正在