`

功能完善的Java连接池调用实例

    博客分类:
  • Java
阅读更多
/** 
* Title: ConnectPool.java 
* Description: 连接池管理器 
* Copyright: Copyright (c) 2009/3/12
* Company: 
* Author : 
* Version 2.0 
*/ 


import java.io.*; 
import java.sql.*; 
import java.util.*; 
import java.util.Date; 

/** 
* 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接 
* 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例. 
*/ 
public class ConnectPool 
{ 
static public ConnectPool instance; // 唯一实例 
static public int clients; 
public Vector drivers = new Vector(); //驱动 
public PrintWriter log; 
public Hashtable pools = new Hashtable(); //连接 

/** 
* 返回唯一实例.如果是第一次调用此方法,则创建实例 
* 
* @return DBConnectionManager 唯一实例 
*/ 
static synchronized public ConnectPool getInstance() 
{ 
if (instance == null) 
{ 
instance = new ConnectPool(); 
} 

clients++; 

return instance; 
} 

/** 
* 建构函数私有以防止其它对象创建本类实例 
*/ 
public ConnectPool() { 
init(); 
} 

/** 
* 将连接对象返回给由名字指定的连接池 
* 
* @param name 在属性文件中定义的连接池名字 
* @param con 连接对象 
*/ 
public void freeConnection(String name, Connection con) 
{ 
DBConnectionPool pool = (DBConnectionPool) pools.get(name); 
if (pool != null) 
{ 
pool.freeConnection(con); 
} 
else 
{ 
System.out.println("pool ==null"); 
} 
clients--; 
} 

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

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

/** 
* 关闭所有连接,撤销驱动程序的注册 
*/ 
public synchronized void release() 
{ 
// 等待直到最后一个客户程序调用 
if (--clients != 0) 
{ 
return; 
} 

Enumeration allPools = pools.elements(); 
while (allPools.hasMoreElements()) 
{ 
DBConnectionPool pool = (DBConnectionPool) allPools.nextElement(); 
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()); 
} 
} 
} 

/** 
* 根据指定属性创建连接池实例. 
* 
* @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"); 
int max; 
try{ 
max = Integer.valueOf(maxconn).intValue(); 
} 
catch (NumberFormatException e) 
{ 
log("错误的最大连接数限制: " + maxconn + " .连接池: " + poolName); 
max = 0; 
} 
DBConnectionPool pool = new DBConnectionPool(poolName, url, user, password, max); 
pools.put(poolName, pool); 
log("成功创建连接池" + poolName); 
} 
} 
} 

/** 
* 读取属性完成初始化 
*/ 
private void init() 
{ 
try 
{ 
Properties p = new Properties(); 
String configs = System.getProperty("user.dir")+"confdb.properties"; 

System.out.println("configs file local at "+configs); 
FileInputStream is = new FileInputStream(configs); 
Properties dbProps = new Properties(); 
try 
{ 
dbProps.load(is); 
} 
catch (Exception e) 
{ 
System.err.println("不能读取属性文件. " +"请确保db.properties在CLASSPATH指定的路径中"); 
return; 
} 
String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log"); 
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); }catch(Exception e){} 
} 

/** 
171 * 装载和注册所有JDBC驱动程序 
172 * 
173 * @param props 属性 
174 */ 
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(); 
DriverManager.registerDriver(driver); 
drivers.addElement(driver); 
System.out.println(driverClassName); 
log("成功注册JDBC驱动程序" + driverClassName); 
} 
catch (Exception e) 
{ 
log("无法注册JDBC驱动程序: " + 
driverClassName + ", 错误: " + e); 
} 
} 
} 

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

/** 
* 将文本信息与异常写入日志文件 
*/ 
private void log(Throwable e, String msg) 
{ 
log.println(new Date() + ": " + msg); 
e.printStackTrace(log); 
} 

/** 
* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最 
* 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性. 
*/ 

class DBConnectionPool 
{ 
//private int checkedOut; 
private Vector freeConnections = new Vector(); 
private int maxConn; 
private String name; 
private String password; 
private String URL; 
private String user; 

/** 
* 创建新的连接池 
* 
* @param name 连接池名字 
* @param URL 数据库的JDBC URL 
* @param user 数据库帐号,或 null 
* @param password 密码,或 null 
* @param maxConn 此连接池允许建立的最大连接数 
*/ 
public DBConnectionPool(String name, String URL, String user, String password,int maxConn) 
{ 
this.name = name; 
this.URL = URL; 
this.user = user; 
this.password = password; 
this.maxConn = maxConn; 
} 
/** 
* 将不再使用的连接返回给连接池 
* 
* @param con 客户程序释放的连接 
*/ 
public synchronized void freeConnection(Connection con) { 
// 将指定连接加入到向量末尾 
try 
{ 
if(con.isClosed()){System.out.println("before freeConnection con is closed");} 
freeConnections.addElement(con); 
Connection contest = (Connection) freeConnections.lastElement(); 
if(contest.isClosed()){System.out.println("after freeConnection contest is closed");} 
notifyAll(); 
}catch(SQLException e){System.out.println(e);} 
} 

/** 
* 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接 
* 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之, 
* 然后递归调用自己以尝试新的可用连接. 
*/ 
public synchronized Connection getConnection() 
{ 
Connection con = null; 
if (freeConnections.size() > 0) 
{ 
// 获取向量中第一个可用连接 
con = (Connection) freeConnections.firstElement(); 
freeConnections.removeElementAt(0); 
try { 
if (con.isClosed()) 
{ 
log("从连接池" + name+"删除一个无效连接"); 
System.out.println("从连接池" + name+"删除一个无效连接"); 
// 递归调用自己,尝试再次获取可用连接 
con = getConnection(); 
} 
} 
catch (SQLException e) 
{ 
log("从连接池" + name+"删除一个无效连接时错误"); 
System.out.println("从连接池" + name+"删除一个无效连接出错"); 
// 递归调用自己,尝试再次获取可用连接 
con = getConnection(); 
} 
if(freeConnections.size()>maxConn) 
{ System.out.println(" 删除一个溢出连接 "); 
releaseOne(); 
} 
} 


else if((maxConn == 0)||(freeConnections.size()<maxConn)) 
{ 
con = newConnection(); 
} 

return con; 
} 

public synchronized Connection returnConnection() 
{ 
Connection con = null; 
//如果闲置小于最大连接,返回一个新连接 
if(freeConnections.size()<maxConn) 
{ 
con = newConnection(); 
} 
//如果闲置大于最大连接,返回一个可用的旧连接 
else if(freeConnections.size()>=maxConn) 
{ 

con = (Connection) freeConnections.firstElement(); 
System.out.println(" [a 连接池可用连接数 ] : "+"[ "+freeConnections.size()+" ]"); 
freeConnections.removeElementAt(0); 
System.out.println(" [b 连接池可用连接数 ] : "+"[ "+freeConnections.size()+" ]"); 
try 
{ 
if (con.isClosed()) 
{ 
log("从连接池" + name+"删除一个无效连接"); 
System.out.println("从连接池" + name+"删除一个无效连接"); 
returnConnection(); 
} 
}catch (SQLException e) 
{ 
log("从连接池" + name+"删除一个无效连接时错误"); 
System.out.println("从连接池" + name+"删除一个无效连接出错"); 
returnConnection(); 
} 
} 
return con; 
} 

/** 
* 从连接池获取可用连接.可以指定客户程序能够等待的最长时间 
* 参见前一个getConnection()方法. 
* 
* @param timeout 以毫秒计的等待时间限制 
*/ 
public synchronized Connection getConnection(long timeout) 
{ 
long startTime = new Date().getTime(); 
Connection con; 
while ((con = getConnection()) == null) 
{ 
try 
{ 
wait(timeout); 
} 
catch (InterruptedException e) {} 
if ((new Date().getTime() - startTime) >= timeout) { 
// wait()返回的原因是超时 
return null; 
} 
} 
return con; 
} 

/** 
* 关闭所有连接 
*/ 
public synchronized void release() 
{ 
Enumeration allConnections = freeConnections.elements(); 
while (allConnections.hasMoreElements()) 
{ 
Connection con = (Connection) allConnections.nextElement(); 
try { 
con.close(); 
log("关闭连接池" + name+"中的一个连接"); 
} 
catch (SQLException e) 
{ 
log(e, "无法关闭连接池" + name+"中的连接"); 
} 
} 
freeConnections.removeAllElements(); 
} 
/** 
* 关闭一个连接 
*/ 
public synchronized void releaseOne() 
{ 
if(freeConnections.firstElement()!=null) 
{ Connection con = (Connection) freeConnections.firstElement(); 
try { 
con.close(); 
System.out.println("关闭连接池" + name+"中的一个连接"); 
log("关闭连接池" + name+"中的一个连接"); 
} 
catch (SQLException e) 
{ 

System.out.println("无法关闭连接池" + name+"中的一个连接"); 
log(e, "无法关闭连接池" + name+"中的连接"); 
} 
} 
else 
{ 
System.out.println("releaseOne() bug......................................................."); 

} 
} 

/** 
* 创建新的连接 
*/ 
private Connection newConnection() 
{ 
Connection con = null; 
try 
{ 
if (user == null) { 
con = DriverManager.getConnection(URL); 
} 
else{ 
con = DriverManager.getConnection(URL, user, password); 
} 
log("连接池" + name+"创建一个新的连接"); 

} 
catch (SQLException e) { 
log(e, "无法创建下列URL的连接: " + URL); 
return null; 
} 
return con; 
} 
} 
}

================================
/** 
* Title: ConnectPool.java 
* Description: 数据库操作 
* Copyright: Copyright (c) 2002/12/25 
* Company: 
* Author : 
* remark : 加入指针回滚 
* Version 2.0 
*/ 

import java.io.*; 
import com.sjky.pool.*; 
import java.sql.*; 
import java.util.*; 
import java.util.Date; 
import java.net.*; 

public class PoolMan extends ConnectPool { 

private ConnectPool connMgr; 
private Statement stmt; 
private Connection con ; 
private ResultSet rst; 

/** 
*对象连接初始化 
* */ 

public Connection getPool(String name) throws Exception 
{ 
try{ 
connMgr = ConnectPool.getInstance(); 
con = connMgr.getConnection(name); 
}catch(Exception e) 
{ 
System.err.println("不能创建连接!请尝试重启应用服务器"); 

} 
return con; 
} 

/** 
*同以上方法,加入连接空闲等待时间 
*待用方法 
* */ 

public Connection getPool_t(String name, long time) throws Exception 
{ 
try{ 
connMgr = ConnectPool.getInstance(); 
con = connMgr.getConnection(name,time); 
}catch(Exception e) 
{ 
System.err.println("不能创建连接!"); 

} 
return con; 
} 
/** 
*执行查询方法1 
* */ 
public ResultSet executeQuery(String SqlStr) throws Exception 
{ 
ResultSet result = null; 
try 
{ 
stmt = con.createStatement(); 
result = stmt.executeQuery(SqlStr); 
// here add one line by jnma 12.11 
con.commit(); 
} 
catch(java.sql.SQLException e) 
{ 
throw new Exception("执行查询语句出错"); 
} 
return result; 
} 
/** 
*执行查询方法2 
* */ 
public ResultSet getRst(String SqlStr) throws Exception 
{ 
// ResultSet result = null; 
try 
{ 
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); 
rst = stmt.executeQuery(SqlStr); 
// here add one line by jnma 12.11 
con.commit(); 
} 
catch(java.sql.SQLException e) 
{ 
throw new Exception("执行查询语句出错"); 
} 
return rst; 
} 
/** 
*执行更新 
* */ 
public int Update(String SqlStr) throws Exception 
{ 
int result = -1; 
try 
{ 
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); 
result = stmt.executeUpdate(SqlStr); 
// here add one line by jnma 12.11 
con.commit(); 
if(result==0) 
System.out.println("执行delete,update,insert SQL出错"); 
} 
catch(java.sql.SQLException e) 
{ 
System.err.println("执行delete,update,insert SQL出错"); 
} 
return result; 
} 

/** 
*执行事务处理 
* */ 
public boolean handleTransaction(Vector SqlArray) throws Exception 
{ 
boolean result = false; 
int ArraySize = SqlArray.size(); 
try 
{ 
stmt = con.createStatement(); 
con.setAutoCommit(false); 
System.out.println("ArraySize is" +ArraySize); 
for(int i=0;i<ArraySize;i++) 
{ 
System.out.println(" 开始执行语句"+(String)SqlArray.elementAt(i)); 
stmt.executeUpdate((String)SqlArray.elementAt(i)); 
System.out.println(" 执行成功"); 
} 
con.commit(); 
con.setAutoCommit(true) ;//必须 
System.out.println("事务执行成功"); 
result = true; 
} 
catch(java.sql.SQLException e) 
{ 
try 
{ 
System.out.println(e.toString()); 
System.out.println("数据库操作失败"); 
con.rollback(); 
} 
catch(java.sql.SQLException Te) 
{ 
System.err.println("事务出错回滚异常"); 
} 
} 
try 
{ 
con.setAutoCommit(true); 
} 
catch(java.sql.SQLException e) 
{ 
System.err.println("设置自动提交失败"); 
} 
return result; 
} 

/** 
*释放连接 
* */ 
public void close(String name) throws Exception 
{ 
try 
{ 
if(stmt!=null) 
stmt.close(); 
if(con!=null) 
{ 
connMgr.freeConnection(name,con); 

System.out.println(" [c 正在释放一个连接 ] "); 

} 
} 
catch(java.sql.SQLException e) 
{ 
System.err.println("释放连接出错"); 
} 
} 

} 
===========================
属性文件db.properties放在conf下 

#drivers=com.inet.tds.TdsDriver 
#logfile=c: esin-2.1.4DBConnectPool-log.txt 
#test.maxconn=1000 
#test.url=jdbc:inetdae:SERVER:1433?sql7=true 
#test.user=sa 
#test.password=test 

drivers=com.microsoft.jdbc.sqlserver.SQLServerDriver 
logfile=F: esin-2.1.4DBConnectPool-log.txt 
test.maxconn=20 
test.url=jdbc:microsoft:sqlserver://192.168.0.5:1433;DatabaseName=test 
test.user=sa 
test.password=test 


#drivers=oracle.jdbc.driver.OracleDriver 
#logfile=c: esin-2.1.4DBConnectPool-log.txt 
#test.maxconn=100 
#test.url=jdbc:oracle:thin:@192.168.0.10:1521:myhome 
#test.user=system 
#test.password=manager 
#mysql端3306 

#drivers=org.gjt.mm.mysql.Driver 
#logfile=c: esin-2.1.4DBConnectPool-log.txt 
#test.maxconn=100 
#test.url=jdbc:mysql://192.168.0.4:3306/my_test 
#test.user=root 
#test.password=system 
分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    使用JAVA中态代理实现数据库连接池.doc

    "使用 JAVA 中的动态代理实现数据库连接池" 在编写应用服务时,数据库连接池是一个经常需要用到的模块,但是太过频繁的连接数据库对服务性能来说是一个瓶颈。使用缓冲池技术可以消除这个瓶颈。然而,现有的连接池...

    JAVA上百实例源码以及开源项目

    摘要:Java源码,初学实例,EJB调用实例  各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java源码,网络相关,...

    JAVA编程百例(照着例子更容易!)

    实例86 JSP使用数据连接池 实例87 JSP+BEAN的应用 实例88 JSP+BEAN连接数据库 实例89 读取属性文件 实例9 异常的捕获和实现自己的异常类 实例90 上传文件 实例91 读取浏览器文件头 实例92 无状态会话EJB 实例93 有...

    JAVA 范例大全 光盘 资源

    实例196 Tomcat连接池的配置 629 实例197 MySQL数据库的分页形式 633 实例198 连接ODBC数据库的Apple程序 640 第20章 JSP/Servlet技术 644 实例199 JSP与Servlet之间的跳转 644 实例200 简单的JSP多人聊天室 ...

    java范例开发大全

    实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的珠子 485 实例249 余额查询 489 ...

    数据连接池

    * 根据指定属性创建连接池实例. * * @param props 连接池属性 */ private void createPools(Properties props) { Enumeration propNames = props.propertyNames(); while (propNames.hasMoreElements()) { ...

    java范例开发大全源代码

     实例185 多功能排序 310  第11章 Java常用类(教学视频:66分钟) 315  11.1 数学Math类 315  实例186 求圆周率∏值 315  实例187 求对数值 316  实例188 使用取整函数 317  11.2 Random类的...

    Java范例开发大全 (源程序)

     实例185 多功能排序 310  第11章 Java常用类(教学视频:66分钟) 315  11.1 数学Math类 315  实例186 求圆周率∏值 315  实例187 求对数值 316  实例188 使用取整函数 317  11.2 Random类的使用 318 ...

    Java范例开发大全(全书源程序)

    实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的珠子 485 实例249 余额查询...

    java开源包1

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    Java JDK实例宝典

    12 一个数据库连接池 第15章 Applet 15. 1 Applet时钟 15. 2 处理鼠标和键盘事件 15. 3 英文打字游戏 15. 4 Applet间通信 15. 5 汉诺塔游戏 第16章 J2SE 5. 0新特性 16. 1 自动...

    java开源包4

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

    java范例开发大全(pdf&源码)

    实例243 模拟人工服务台(线程连接池) 466 13.6 线程应用实例 471 实例244 下雪的村庄 472 实例245 小飞侠 474 实例246 飞流直下 477 实例247 多线程断点续传 479 实例248 滚动的珠子 485 实例249 余额查询 489 ...

    java开源包6

    BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K(运行时需要slf4j和guava的支持,这二者加...

Global site tag (gtag.js) - Google Analytics