java连接池实现.docx

上传人:b****7 文档编号:10613796 上传时间:2023-02-21 格式:DOCX 页数:25 大小:18.99KB
下载 相关 举报
java连接池实现.docx_第1页
第1页 / 共25页
java连接池实现.docx_第2页
第2页 / 共25页
java连接池实现.docx_第3页
第3页 / 共25页
java连接池实现.docx_第4页
第4页 / 共25页
java连接池实现.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

java连接池实现.docx

《java连接池实现.docx》由会员分享,可在线阅读,更多相关《java连接池实现.docx(25页珍藏版)》请在冰豆网上搜索。

java连接池实现.docx

java连接池实现

虽然现在用APACHECOMMONSDBCP可以非常方便的建立数据库连接池,

但是像这篇文章把数据库连接池的内部原理写的这么透彻,注视这么完整,

真是非常难得,让开发人员可以更深层次的理解数据库连接池,真是非常感

谢这篇文章的作者。

importjava.sql.Connection;

importjava.sql.DatabaseMetaData;

importjava.sql.Driver;

importjava.sql.DriverManager;

importjava.sql.SQLException;

importjava.sql.Statement;

importjava.util.Enumeration;

importjava.util.Vector;

publicclassConnectionPool{

privateStringjdbcDriver="";//数据库驱动

privateStringdbUrl="";//数据URL

privateStringdbUsername="";//数据库用户名

privateStringdbPassword="";//数据库用户密码

privateStringtestTable="";//测试连接是否可用的测试表名,默认没有测试表

privateintinitialConnections=10;//连接池的初始大小

privateintincrementalConnections=5;//连接池自动增加的大小

privateintmaxConnections=50;//连接池最大的大小

privateVectorconnections=null;//存放连接池中数据库连接的向量,初始时为null

//它中存放的对象为PooledConnection型

/**

*构造函数

*

*@paramjdbcDriverStringJDBC驱动类串

*@paramdbUrlString数据库URL

*@paramdbUsernameString连接数据库用户名

*@paramdbPasswordString连接数据库用户的密码

*

*/

publicConnectionPool(StringjdbcDriver,StringdbUrl,StringdbUsername,StringdbPassword){

this.jdbcDriver=jdbcDriver;

this.dbUrl=dbUrl;

this.dbUsername=dbUsername;

this.dbPassword=dbPassword;

}

/**

*返回连接池的初始大小

*

*@return初始连接池中可获得的连接数量

*/

publicintgetInitialConnections(){

returnthis.initialConnections;

}

/**

*设置连接池的初始大小

*

*@param用于设置初始连接池中连接的数量

*/

publicvoidsetInitialConnections(intinitialConnections){

this.initialConnections=initialConnections;

}

/**

*返回连接池自动增加的大小、

*

*@return连接池自动增加的大小

*/

publicintgetIncrementalConnections(){

returnthis.incrementalConnections;

}

/**

*设置连接池自动增加的大小

*@param连接池自动增加的大小

*/

publicvoidsetIncrementalConnections(intincrementalConnections){

this.incrementalConnections=incrementalConnections;

}

/**

*返回连接池中最大的可用连接数量

*@return连接池中最大的可用连接数量

*/

publicintgetMaxConnections(){

returnthis.maxConnections;

}

/**

*设置连接池中最大可用的连接数量

*

*@param设置连接池中最大可用的连接数量值

*/

publicvoidsetMaxConnections(intmaxConnections){

this.maxConnections=maxConnections;

}

/**

*获取测试数据库表的名字

*

*@return测试数据库表的名字

*/

publicStringgetTestTable(){

returnthis.testTable;

}

/**

*设置测试表的名字

*@paramtestTableString测试表的名字

*/

publicvoidsetTestTable(StringtestTable){

this.testTable=testTable;

}

/**

*

*创建一个数据库连接池,连接池中的可用连接的数量采用类成员

*initialConnections中设置的值

*/

publicsynchronizedvoidcreatePool()throwsException{

//确保连接池没有创建

//如果连接池己经创建了,保存连接的向量connections不会为空

if(connections!

=null){

return;//如果己经创建,则返回

}

//实例化JDBCDriver中指定的驱动类实例

Driverdriver=(Driver)(Class.forName(this.jdbcDriver).newInstance());

DriverManager.registerDriver(driver);//注册JDBC驱动程序

//创建保存连接的向量,初始时有0个元素

connections=newVector();

//根据initialConnections中设置的值,创建连接。

createConnections(this.initialConnections);

System.out.println("数据库连接池创建成功!

");

}

/**

*创建由numConnections指定数目的数据库连接,并把这些连接

*放入connections向量中

*

*@paramnumConnections要创建的数据库连接的数目

*/

@SuppressWarnings("unchecked")

privatevoidcreateConnections(intnumConnections)throwsSQLException{

//循环创建指定数目的数据库连接

for(intx=0;x

//是否连接池中的数据库连接的数量己经达到最大?

最大值由类成员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){

}

}

/**

*

*内部使用的用于保存连接池中连接对象的类

*此类中有两个成员,一个是数据库的连接,另一个是指示此连接是否

*正在

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 考试认证 > 从业资格考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1