数据库连接池的应用.docx
- 文档编号:10661527
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:18
- 大小:48.55KB
数据库连接池的应用.docx
《数据库连接池的应用.docx》由会员分享,可在线阅读,更多相关《数据库连接池的应用.docx(18页珍藏版)》请在冰豆网上搜索。
数据库连接池的应用
应用数据库连接池共用到三个文件。
文件一:
主要的功能为:
标明要连接的数据库的名称,用户名,密码。
drivers=net.sourceforge.jtds.jdbc.Driver
logfile=c:
\\DBConnectionManager2.log
idb.url=jdbc:
jtds:
sqlserver:
//localhost:
1433/;DatabaseName=book
book为自己的数据库名。
idb.maxconn=2
2用于指定建立的最大的连接条数。
idb.user=sa
sa代表数据库的用户名。
idb.password=""
数据库的密码。
改好后保存,会形成新的文件:
此文件的作用是:
没有什么作用。
只是用EditPlus找开此中会形成这样的一个文件。
如果要对此文件进行了修改。
那么要重启apach.
文件二:
里面是连接池的编写程序,主要是以备后面调用。
在DOS当中运行此文件,运行方法:
1、选转到D盘:
方法:
D:
然后打回车。
2、利用cd的方法转到cnbook\web-inf\classes>此处不能转到db下再执行.java文件。
3、javacdb\DBConnectionManager.java然后javaDBConnectionManager后就会形成相应的class文件。
(此处必须这样写,因为里面含有两个类,有一个类在运行时会用到另一个类,在文件三中才用这个解释方法:
在文件三编译时会用到文件二中生成的两个类,所以只要到转到classes即可,而此处只需转到db下,然后javacDBConnectionManager.java对它进行编译就会生成两个.classes文件。
)
在DOS中运可生成两个class文件。
因为。
java文件中有两个类,所以形成两个。
Class文件,分别为:
packagedb;
importjava.io.*;
importjava.sql.*;
importjava.util.*;
importjava.util.Date;
/**连接池
*管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接
*池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
*/
publicclassDBConnectionManager{
staticprivateDBConnectionManagerinstance;//唯一实例
staticprivateintclients;
privateVectordrivers=newVector();
privatePrintWriterlog;
privateHashtablepools=newHashtable();
/**
*返回唯一实例.如果是第一次调用此方法,则创建实例
*
*@returnDBConnectionManager唯一实例
*/
staticsynchronizedpublicDBConnectionManagergetInstance(){
if(instance==null){
instance=newDBConnectionManager();
}
clients++;
returninstance;
}
/**
*建构函数私有以防止其它对象创建本类实例
*/
privateDBConnectionManager(){
init();
}
/**
*将连接对象返回给由名字指定的连接池
*
*@paramname在属性文件中定义的连接池名字
*@paramcon连接对象
*/
publicvoidfreeConnection(Stringname,Connectioncon){
DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
if(pool!
=null){
pool.freeConnection(con);
}
}
/**
*获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
*限制,则创建并返回新连接
*
*@paramname在属性文件中定义的连接池名字
*@returnConnection可用连接或null
*/
publicConnectiongetConnection(Stringname){
DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
if(pool!
=null){
returnpool.getConnection();
}
returnnull;
}
/**
*获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
*则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
*
*@paramname连接池名字
*@paramtime以毫秒计的等待时间
*@returnConnection可用连接或null
*/
publicConnectiongetConnection(Stringname,longtime){
DBConnectionPoolpool=(DBConnectionPool)pools.get(name);
if(pool!
=null){
returnpool.getConnection(time);
}
returnnull;
}
/**
*关闭所有连接,撤销驱动程序的注册
*/
publicsynchronizedvoidrelease(){
//等待直到最后一个客户程序调用
if(--clients!
=0){
return;
}
EnumerationallPools=pools.elements();
while(allPools.hasMoreElements()){
DBConnectionPoolpool=(DBConnectionPool)allPools.nextElement();
pool.release();
}
EnumerationallDrivers=drivers.elements();
while(allDrivers.hasMoreElements()){
Driverdriver=(Driver)allDrivers.nextElement();
try{
DriverManager.deregisterDriver(driver);
log("撤销JDBC驱动程序"+driver.getClass().getName()+"的注册");
}
catch(SQLExceptione){
log(e,"无法撤销下列JDBC驱动程序的注册:
"+driver.getClass().getName());
}
}
}
/**
*根据指定属性创建连接池实例.
*
*@paramprops连接池属性
*/
privatevoidcreatePools(Propertiesprops){
EnumerationpropNames=props.propertyNames();
while(propNames.hasMoreElements()){
Stringname=(String)propNames.nextElement();
if(name.endsWith(".url")){
StringpoolName=name.substring(0,name.lastIndexOf("."));
Stringurl=props.getProperty(poolName+".url");
if(url==null){
log("没有为连接池"+poolName+"指定URL");
continue;
}
Stringuser=props.getProperty(poolName+".user");
Stringpassword=props.getProperty(poolName+".password");
Stringmaxconn=props.getProperty(poolName+".maxconn","0");
intmax;
try{
max=Integer.valueOf(maxconn).intValue();
}
catch(NumberFormatExceptione){
log("错误的最大连接数限制:
"+maxconn+".连接池:
"+poolName);
max=0;
}
DBConnectionPoolpool=
newDBConnectionPool(poolName,url,user,password,max);
pools.put(poolName,pool);
log("成功创建连接池"+poolName);
}
}
}
/**
*读取属性完成初始化
*/
privatevoidinit(){
InputStreamis=getClass().getResourceAsStream("db.properties");
PropertiesdbProps=newProperties();
try{
dbProps.load(is);
}
catch(Exceptione){
System.err.println("不能读取属性文件."+
"请确保db.properties在CLASSPATH指定的路径中");
return;
}
StringlogFile=dbProps.getProperty("logfile","DBConnectionManager.log");
try{
log=newPrintWriter(newFileWriter(logFile,true),true);
}
catch(IOExceptione){
System.err.println("无法打开日志文件:
"+logFile);
log=newPrintWriter(System.err);
}
loadDrivers(dbProps);
createPools(dbProps);
}
/**
*装载和注册所有JDBC驱动程序
*
*@paramprops属性
*/
privatevoidloadDrivers(Propertiesprops){
StringdriverClasses=props.getProperty("drivers");
StringTokenizerst=newStringTokenizer(driverClasses);
while(st.hasMoreElements()){
StringdriverClassName=st.nextToken().trim();
try{
Driverdriver=(Driver)
Class.forName(driverClassName).newInstance();
DriverManager.registerDriver(driver);
drivers.addElement(driver);
log("成功注册JDBC驱动程序"+driverClassName);
}
catch(Exceptione){
log("无法注册JDBC驱动程序:
"+
driverClassName+",错误:
"+e);
}
}
}
/**
*将文本信息写入日志文件
*/
privatevoidlog(Stringmsg){
log.println(newDate()+":
"+msg);
}
/**
*将文本信息与异常写入日志文件
*/
privatevoidlog(Throwablee,Stringmsg){
log.println(newDate()+":
"+msg);
e.printStackTrace(log);
}
/**
*此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
*大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*/
classDBConnectionPool{
privateintcheckedOut;
privateVectorfreeConnections=newVector();
privateintmaxConn;
privateStringname;
privateStringpassword;
privateStringURL;
privateStringuser;
/**
*创建新的连接池
*
*@paramname连接池名字
*@paramURL数据库的JDBCURL
*@paramuser数据库帐号,或null
*@parampassword密码,或null
*@parammaxConn此连接池允许建立的最大连接数
*/
publicDBConnectionPool(Stringname,StringURL,Stringuser,Stringpassword,
intmaxConn){
this.name=name;
this.URL=URL;
this.user=user;
this.password=password;
this.maxConn=maxConn;
}
/**
*将不再使用的连接返回给连接池
*
*@paramcon客户程序释放的连接
*/
publicsynchronizedvoidfreeConnection(Connectioncon){
//将指定连接加入到向量末尾
log("释放前"+freeConnections.size());
freeConnections.addElement(con);
checkedOut--;
notifyAll();
log("释放后"+freeConnections.size());
}
/**
*从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
*数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
*然后递归调用自己以尝试新的可用连接.
*/
publicsynchronizedConnectiongetConnection(){
Connectioncon=null;
if(freeConnections.size()>0){
//获取向量中第一个可用连接
con=(Connection)freeConnections.firstElement();
freeConnections.removeElementAt(0);
try{
if(con.isClosed()){
log("从连接池"+name+"删除一个无效连接");
//递归调用自己,尝试再次获取可用连接
con=getConnection();
}
}
catch(SQLExceptione){
log("从连接池"+name+"删除一个无效连接");
//递归调用自己,尝试再次获取可用连接
con=getConnection();
}
}
elseif(maxConn==0||checkedOut con=newConnection(); } if(con! =null){ checkedOut++; } log("获取连接前"+freeConnections.size()); returncon; } /** *从连接池获取可用连接.可以指定客户程序能够等待的最长时间 *参见前一个getConnection()方法. * *@paramtimeout以毫秒计的等待时间限制 */ publicsynchronizedConnectiongetConnection(longtimeout){ longstartTime=newDate().getTime(); Connectioncon; while((con=getConnection())==null){ try{ wait(timeout); } catch(InterruptedExceptione){} if((newDate().getTime()-startTime)>=timeout){ //wait()返回的原因是超时 returnnull; } } returncon; } /** *关闭所有连接 */ publicsynchronizedvoidrelease(){ EnumerationallConnections=freeConnections.elements(); while(allConnections.hasMoreElements()){ Connectioncon=(Connection)allConnections.nextElement(); try{ con.close(); log("关闭连接池"+name+"中的一个连接"); } catch(SQLExceptione){ log(e,"无法关闭连接池"+name+"中的连接"); } } freeConnections.removeAllElements(); } /** *创建新的连接 */ privateConnectionnewConnection(){ Connectioncon=null; try{ if(user==null){ con=DriverManager.getConnection(URL); } else{ con=DriverManager.getConnection(URL,user,password); } log("连接池"+name+"创建一个新的连接"); } catch(SQLExceptione){ log(e,"无法创建下列URL的连接: "+URL); returnnull; } returncon; } } } 文件三: 主要用于连接数据库。 编缉方法: 在dos当中转到cnbook\web-inf\classes>javacdb\dbconn.java就会形成.class文件 。 为什么此时路径只需写到classes即可。 因为在dbconn.java编译中用到了db包中的文件二中的己运行成功的两个文件(即上面的两个.class文件。 )所以如果把路径写到db后再运行就会提示找不到所要引用的文件。 packagedb; importjava.sql.*; importdb.DBConnectionManager; publicclassdbconn { DBConnectionManagerdba=null; Connectionconn=null; ResultSetrs=null; Statementstmt=null; publicdbconn() { try{ dba=DBConnectionManager.getInstance(); conn=dba.getConnection("idb"); } catch(Exceptione){ System.out.println(e.toString()); } } publicResultSetQuery(Stringsql) { try{ stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); rs=stmt.executeQuery(sql); } catch(Exceptione) { System.out.println(e.toString()); } finally{ returnrs; } } publicintUpdate(Stringsql) {inti=0; try { stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); i=stmt.executeUpdate(sql); } catch(Exceptione) { System.out.println(e.toString()); } returni; } publicvoidclose() { try{ dba.freeConnection("idb",conn); } catch(Exceptione) { dba.freeConnection("idb",conn); System.out.println(e.toString()); } } } 建了 文件之后会在c盘生成一个DBConnectionManager2文件。 此文件的作用是用于查看数据库连接池是否连接成功。 SatAug1215: 20: 53CST2000: 成功注册JDBC驱动程序net.sourceforge.jtds.jdbc.Driver
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据库连接 应用