求一个STRUTS2 SQLSERVER2000的连接池的代码,最好有个例子 如题,网上找了很久,没找到,以前只用过JSP MYSQL的连接池,实在不想花时间去一个个试了-_- 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 package com.cc.connectionpool;import java.io.IOException;import java.sql.*;import java.util.Date;import javax.management.StringValueExp;public class ConnectionPool implements Runnable { //private boolean _debug=false; private Thread runner; //数据库池线程 private Connection[] connPool; //数据库池中的连接数组 private int[] connStatus; //记录连接池中每个连接的状态。 //当connStatus[i]=0时,代表连接可用,为1时代码被用户锁定, // 值为2时代表被管理员线程锁定。 private long[] connLockTime; //记录每个连接被锁定的时间 private long[] connCreateTime; //记录每个连接被创建的时间 private String[] connID; //记录每个连接的标识号 private String dbdriver,dbserver,dbuser,dbpassword; //dbdriver表示连接驱动,dbserver表示注册字符,dbuser表示用户,dbpassword表示用户口令 private int currConnections,connLast,minconns,maxconns,maxconnMSec; private boolean available=true; //当连接池撤销时值为false,调用getConnetcion()方法时检查available private SQLWarning currSQLWarning; //定义两个构造方法,其中一个为默认参数 public ConnectionPool(String dbdriver,String dbserver,String dbuser,String dbpassword,int minconns,int maxconns,double maxconntime){ try { initConnectionPool(dbdriver,dbserver,dbuser,dbpassword,minconns,maxconns,maxconntime); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }/* public ConnectionPool(){ try { String dbdriver="com.microsoft.sqlserver.jdbc.SQLServerDriver"; String dbserver="jdbc:sqlserver://localhost:1433;DatabaseName=Player"; String username="yuqing"; String password="1234"; initConnectionPool(dbdriver,dbserver,username,password,30,100,0.1); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }*/ public void initConnectionPool(String dbdriver,String dbserver,String dbuser,String dbpassword,int minconns,int maxconns,double maxconntime)throws IOException{ connPool=new Connection[maxconns]; connStatus=new int[maxconns]; connLockTime=new long[maxconns]; connCreateTime=new long[maxconns]; connID=new String[maxconns]; currConnections=minconns; this.dbdriver=dbdriver; this.dbserver=dbserver; this.dbuser=dbuser; this.dbpassword=dbpassword; maxconnMSec=(int)(maxconntime*3600*1000); //maxconntime表示的是连接重置之间的最大时间差 if(maxconnMSec<60000){ maxconnMSec=60000; }//当maxconnMSec小于一分钟,则赋值为一分钟 init(); runner=new Thread(this); runner.start(); } //下面是初始化方法,功能是建立指定初始个数的连接,若某个连接创建不成功,将等待15秒再继续访问数据库, //此方法用一个dbLoop循环,使得等待时间超过5分钟将会输出错误 private void init(){ boolean connectionsSucceeded=false; int dbLoop=20; try{ for(int i=0;i<dbLoop;i++){ try{ for(int j=1;j<currConnections;j++){ createConn(j); } connectionsSucceeded=true; break; //若每个连接都创建成功便跳出所有循环,初始化完毕。 }catch(SQLException e){ System.out.println("--->Attempt("+String.valueOf(i)+"of"+String.valueOf(dbLoop)+")failed to create new connections set at startup:"); System.out.println(" "+e); System.out.println(" Will try again in 15 seconds..."); e.printStackTrace(); try{ Thread.sleep(15000);//若创建某连接不成功,则等待15秒后继续尝试去连接数据库,本方法最外层的循环执行20次,表明最大的等待时间为15*20=5分钟。 }catch(InterruptedException e1){e1.printStackTrace();} } } if(!connectionsSucceeded){ //如果20次循环之后连接依然不能创建成功,证明等待数据库的重启时间已经超过5分钟,此时将输出提示错误信息。 System.out.println("\r\nAll attempts at connecting to Database exhausted!"); throw new IOException(); } }catch(Exception e){ e.printStackTrace(); } } //下面该方法用于真正创建一个连接。 private void createConn(int i) throws SQLException{ Date now=new Date(); try{ Class.forName(dbdriver); connPool[i]=DriverManager.getConnection(dbserver,dbuser,dbpassword); connStatus[i]=0; connID[i]=connPool[i].toString(); connLockTime[i]=0; connCreateTime[i]=0; connCreateTime[i]=now.getTime(); }catch(ClassNotFoundException e2){ e2.printStackTrace(); throw new SQLException(e2.getMessage()); } } //run()方法是本类最重要的方法,它有三个功能: //(1)它不断地获取连接过程中的警告信息并输出; //(2)它不断得测试每个连接的存在时间是否大于最大需重置的时间maxconnMSec,若大于则抛出异常进行重启; //(3)它不断地测试连接池中的连接是否存在问题,若存在问题便进行重启。 public void run() { // TODO Auto-generated method stub Statement stmt=null; String surrCatalog=null; //线程执行无限循环,不断进行检查工作。 for(;;){ //下面这个循环用于获取连接过程中的警告信息。 for(int i=0;i<currConnections;i++){ try{ currSQLWarning=connPool[i].getWarnings(); if(currSQLWarning!=null){ System.out.println("Warning on connection"+String.valueOf(i)+" "+currSQLWarning); connPool[i].clearWarnings(); } }catch(SQLException e){ System.out.println("Cannot access Warnings:"+e); } } for(int i=0;i<currConnections;i++){ long age=System.currentTimeMillis()-connCreateTime[i]; synchronized(connStatus){ if(connStatus[i]>0)continue; //如果连接状态值大于0,表示它正在被使用,则下次再经进行测试。 connStatus[i]=2; //如果连接状态是等于0,表示其处于空闲,则对他进行锁定,以便进行测试。 } try{ if(age>maxconnMSec){ throw new SQLException(); } stmt=connPool[i].createStatement(); connStatus[i]=0; //获取stmt结果,使得连接处于开启状态,以进行下面的测试,stmt获取完便将连接的状态改为空闲。 if(connPool[i].isClosed()){throw new SQLException();} //进行测试,如果连接处于关闭状态,说明这个连接存在问题,则抛出异常。 }catch(SQLException e){ try{ connPool[i].close(); createConn(i); //若连接存在问题,则重启连接。 }catch(SQLException e1){ System.out.println("Failed:"+e1); connStatus[i]=0; //若连接存在问题又重启不了,则将其改为空闲状态,留到下次再检测。 } }finally{ try{ if(stmt!=null) stmt.close(); }catch(SQLException e1){}; } } try { Thread.sleep(20000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); return; } //检查完一个连接后等待20秒再进行下次检测 }//end for(;;) } // getConnection()用来顺序获取连接池中的一个连接。 public Connection getConnection(){ Connection conn=null; //建立连接对象,用于后面赋值返回 if(available){ boolean getOne=false; //用于表示是否找到一个可用的连接。 //下面这个循环执行10次,每次尝试从池中寻找一个连接,若10次都找不到一个连接,便返回null。 for(int outerloop=1;outerloop<=10;outerloop++){ try{ int loop=0; //用于记录在一个池中寻找失败的次数,若失败次数大于等于池中的连接数,则代表所有的连接都被使用。 int roundRobin=connLast+1; //记录所访问的连接的下标,若下标大于最大下标,则赋值为0,代表重新从第一个连接开始判断。 //connLast表示上次所获取连接的下标,用connLast记录可以实现按顺序分配连接。 if(roundRobin>=currConnections){ roundRobin=0; } do{ synchronized(connStatus){ if((connStatus[roundRobin]<1)&&(!connPool[roundRobin].isClosed())){ conn=connPool[roundRobin]; connStatus[roundRobin]=1; connLockTime[roundRobin]=System.currentTimeMillis(); connLast=roundRobin; getOne=true; break; }else{ loop++; roundRobin++; if(roundRobin>=currConnections)roundRobin=0; } } }while((getOne==false)&&(loop<currConnections)); }catch(SQLException e1){} if(getOne){break;} else{ synchronized(this){ if(currConnections<maxconns){ try{ createConn(currConnections); currConnections++; }catch(SQLException e){ System.out.println("Unable to create new connection"+String.valueOf(currConnections-1)); System.out.println("Exception :"+e); } } } try { Thread.sleep(2000); //执行完一次循环之后,若所有连接都被使用,则等待2秒再进行下一次的尝试。 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("----->Connections Exhausted!Will wait and try"+"again in outer loop"+String.valueOf(outerloop)); } } }else{ System.out.println("Unsuccessful getConnection() request during destroy()"); //若available=0,表示连接池不可用,输出提示错误信息。 } return conn; } public int idOfConnection(Connection conn){ int match; String tag; try{ tag=conn.toString(); //获取conn的标识 }catch(NullPointerException e){tag="none";} match=-1; for(int i=0;i<currConnections;i++){ if(connID[i].equals(tag)){ match=i; //如果连接池中包含conn所描述的连接,则返回其下标,若无,则返回-1。 break; } } return match; } // freeConnection(conn)方法用于将conn是释放,返回到连接池中供其他连接所使用。 public String freeConnection(Connection conn){ String res=""; int thisconn=idOfConnection(conn); if(thisconn>=0){ connStatus[thisconn]=0; //若此连接有唯一标识,则利用其下标,将其状态改为空闲。 res="freed"+conn.toString(); }else{ System.out.println("---->Could not free connection!!!"+"Try to close if directly"); try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return res; } // 此方法用于返回某连接的寿命。 public long getAge(Connection conn){ int thisconn=idOfConnection(conn); return System.currentTimeMillis()-connLockTime[thisconn]; } //此方法用于关闭后台线程,并在关闭millis时间后断开所有的连接 public void destroy(int millis)throws SQLException{ available=false; runner.interrupt(); try { runner.join(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } long startTime=System.currentTimeMillis(); int useCount; while((useCount=getUseCount())>0&&System.currentTimeMillis()-startTime<=millis){ try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 用一个循环,使得当前时间与方法开始调用的时间之差大于指定的millis之后,关闭所有连接。 for(int i=0;i<currConnections;i++){ connPool[i].close(); } if(useCount>0){ throw new SQLException(); } } //默认销毁方法,millis值为10秒 public void destroy(){ try { destroy(10000); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //返回正在被使用的连接数。 public int getUseCount(){ int useCount=0; synchronized(connStatus){ for(int i=0;i<currConnections;i++){ if(connStatus[i]>0){ useCount++; } } } return useCount; } //返回动态连接池中现有的连接数 public int getSize(){ return currConnections; }}//end class 这是一种连接池的java代码,上面的注释我写的很清楚了。使用的时候直接给它的构造函数赋值就行了,驱动方面的代码baidu有的下,sqlserver的驱动代码一般是com.microsoft.sqlserver.jdbc.SQLServerDriver,连接代码一般是jdbc:sqlserver://localhost:1433;DatabaseName=[name]。 jdbc连接疑问 [求解]JAVA EE 用struts2 通过数据库实现登录实例出现问题 java PDF 我在运行程序时出现:实体bean不能加载的异常。可是这个实体bean我压根就没用到啊,也没有建立跟这个实体bean的外键关联 java做的简历有照片上传问题?? 添加外发邮件模块 XML解析 有个spring的问题,请教高手,高分谢谢! 使用weblogic操作oracle数据库游标出错 SOS哪位大虾能给在下J2EE完整的例子???急 struts2的JSP编译执行后还是SERVLET吗 分页查询效率为什么高?
import java.sql.*;
import java.util.Date;
import javax.management.StringValueExp;public class ConnectionPool implements Runnable {
//private boolean _debug=false;
private Thread runner; //数据库池线程
private Connection[] connPool; //数据库池中的连接数组
private int[] connStatus; //记录连接池中每个连接的状态。
//当connStatus[i]=0时,代表连接可用,为1时代码被用户锁定,
// 值为2时代表被管理员线程锁定。
private long[] connLockTime; //记录每个连接被锁定的时间
private long[] connCreateTime; //记录每个连接被创建的时间
private String[] connID; //记录每个连接的标识号
private String dbdriver,dbserver,dbuser,dbpassword;
//dbdriver表示连接驱动,dbserver表示注册字符,dbuser表示用户,dbpassword表示用户口令
private int currConnections,connLast,minconns,maxconns,maxconnMSec;
private boolean available=true; //当连接池撤销时值为false,调用getConnetcion()方法时检查available
private SQLWarning currSQLWarning;
//定义两个构造方法,其中一个为默认参数
public ConnectionPool(String dbdriver,String dbserver,String dbuser,String dbpassword,int minconns,int maxconns,double maxconntime){
try {
initConnectionPool(dbdriver,dbserver,dbuser,dbpassword,minconns,maxconns,maxconntime);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
public ConnectionPool(){
try {
String dbdriver="com.microsoft.sqlserver.jdbc.SQLServerDriver";
String dbserver="jdbc:sqlserver://localhost:1433;DatabaseName=Player";
String username="yuqing";
String password="1234";
initConnectionPool(dbdriver,dbserver,username,password,30,100,0.1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
*/
public void initConnectionPool(String dbdriver,String dbserver,String dbuser,String dbpassword,int minconns,int maxconns,double maxconntime)throws IOException{
connPool=new Connection[maxconns];
connStatus=new int[maxconns];
connLockTime=new long[maxconns];
connCreateTime=new long[maxconns];
connID=new String[maxconns];
currConnections=minconns;
this.dbdriver=dbdriver;
this.dbserver=dbserver;
this.dbuser=dbuser;
this.dbpassword=dbpassword;
maxconnMSec=(int)(maxconntime*3600*1000);
//maxconntime表示的是连接重置之间的最大时间差
if(maxconnMSec<60000){
maxconnMSec=60000;
}//当maxconnMSec小于一分钟,则赋值为一分钟
init();
runner=new Thread(this);
runner.start();
}
//下面是初始化方法,功能是建立指定初始个数的连接,若某个连接创建不成功,将等待15秒再继续访问数据库,
//此方法用一个dbLoop循环,使得等待时间超过5分钟将会输出错误
private void init(){
boolean connectionsSucceeded=false;
int dbLoop=20;
try{
for(int i=0;i<dbLoop;i++){
try{
for(int j=1;j<currConnections;j++){
createConn(j);
}
connectionsSucceeded=true;
break; //若每个连接都创建成功便跳出所有循环,初始化完毕。
}catch(SQLException e){
System.out.println("--->Attempt("+String.valueOf(i)+"of"+String.valueOf(dbLoop)+")failed to create new connections set at startup:");
System.out.println(" "+e);
System.out.println(" Will try again in 15 seconds...");
e.printStackTrace();
try{
Thread.sleep(15000);//若创建某连接不成功,则等待15秒后继续尝试去连接数据库,本方法最外层的循环执行20次,表明最大的等待时间为15*20=5分钟。
}catch(InterruptedException e1){e1.printStackTrace();}
}
}
if(!connectionsSucceeded){
//如果20次循环之后连接依然不能创建成功,证明等待数据库的重启时间已经超过5分钟,此时将输出提示错误信息。
System.out.println("\r\nAll attempts at connecting to Database exhausted!");
throw new IOException();
}
}catch(Exception e){
e.printStackTrace();
}
}
private void createConn(int i) throws SQLException{
Date now=new Date();
try{
Class.forName(dbdriver);
connPool[i]=DriverManager.getConnection(dbserver,dbuser,dbpassword);
connStatus[i]=0;
connID[i]=connPool[i].toString();
connLockTime[i]=0;
connCreateTime[i]=0;
connCreateTime[i]=now.getTime();
}catch(ClassNotFoundException e2){
e2.printStackTrace();
throw new SQLException(e2.getMessage());
}
}
//run()方法是本类最重要的方法,它有三个功能:
//(1)它不断地获取连接过程中的警告信息并输出;
//(2)它不断得测试每个连接的存在时间是否大于最大需重置的时间maxconnMSec,若大于则抛出异常进行重启;
//(3)它不断地测试连接池中的连接是否存在问题,若存在问题便进行重启。
public void run() {
// TODO Auto-generated method stub
Statement stmt=null;
String surrCatalog=null;
//线程执行无限循环,不断进行检查工作。
for(;;){
//下面这个循环用于获取连接过程中的警告信息。
for(int i=0;i<currConnections;i++){
try{
currSQLWarning=connPool[i].getWarnings();
if(currSQLWarning!=null){
System.out.println("Warning on connection"+String.valueOf(i)+" "+currSQLWarning);
connPool[i].clearWarnings();
}
}catch(SQLException e){
System.out.println("Cannot access Warnings:"+e);
}
}
for(int i=0;i<currConnections;i++){
long age=System.currentTimeMillis()-connCreateTime[i];
synchronized(connStatus){
if(connStatus[i]>0)continue; //如果连接状态值大于0,表示它正在被使用,则下次再经进行测试。
connStatus[i]=2; //如果连接状态是等于0,表示其处于空闲,则对他进行锁定,以便进行测试。
}
try{
if(age>maxconnMSec){
throw new SQLException();
}
stmt=connPool[i].createStatement();
connStatus[i]=0; //获取stmt结果,使得连接处于开启状态,以进行下面的测试,stmt获取完便将连接的状态改为空闲。
if(connPool[i].isClosed()){throw new SQLException();} //进行测试,如果连接处于关闭状态,说明这个连接存在问题,则抛出异常。
}catch(SQLException e){
try{
connPool[i].close();
createConn(i); //若连接存在问题,则重启连接。
}catch(SQLException e1){
System.out.println("Failed:"+e1);
connStatus[i]=0; //若连接存在问题又重启不了,则将其改为空闲状态,留到下次再检测。
}
}finally{
try{
if(stmt!=null)
stmt.close();
}catch(SQLException e1){};
}
}
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
} //检查完一个连接后等待20秒再进行下次检测
}//end for(;;)
}
// getConnection()用来顺序获取连接池中的一个连接。
public Connection getConnection(){
Connection conn=null; //建立连接对象,用于后面赋值返回
if(available){
boolean getOne=false; //用于表示是否找到一个可用的连接。
//下面这个循环执行10次,每次尝试从池中寻找一个连接,若10次都找不到一个连接,便返回null。
for(int outerloop=1;outerloop<=10;outerloop++){
try{
int loop=0; //用于记录在一个池中寻找失败的次数,若失败次数大于等于池中的连接数,则代表所有的连接都被使用。
int roundRobin=connLast+1; //记录所访问的连接的下标,若下标大于最大下标,则赋值为0,代表重新从第一个连接开始判断。
//connLast表示上次所获取连接的下标,用connLast记录可以实现按顺序分配连接。
if(roundRobin>=currConnections){
roundRobin=0;
}
do{
synchronized(connStatus){
if((connStatus[roundRobin]<1)&&(!connPool[roundRobin].isClosed())){
conn=connPool[roundRobin];
connStatus[roundRobin]=1;
connLockTime[roundRobin]=System.currentTimeMillis();
connLast=roundRobin;
getOne=true;
break;
}else{
loop++;
roundRobin++;
if(roundRobin>=currConnections)roundRobin=0;
}
}
}while((getOne==false)&&(loop<currConnections));
}catch(SQLException e1){}
if(getOne){break;}
else{
synchronized(this){
if(currConnections<maxconns){
try{
createConn(currConnections);
currConnections++;
}catch(SQLException e){
System.out.println("Unable to create new connection"+String.valueOf(currConnections-1));
System.out.println("Exception :"+e);
}
}
}
try {
Thread.sleep(2000); //执行完一次循环之后,若所有连接都被使用,则等待2秒再进行下一次的尝试。
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("----->Connections Exhausted!Will wait and try"+"again in outer loop"+String.valueOf(outerloop));
}
}
}else{
System.out.println("Unsuccessful getConnection() request during destroy()"); //若available=0,表示连接池不可用,输出提示错误信息。
}
return conn;
} public int idOfConnection(Connection conn){
int match;
String tag;
try{
tag=conn.toString(); //获取conn的标识
}catch(NullPointerException e){tag="none";}
match=-1;
for(int i=0;i<currConnections;i++){
if(connID[i].equals(tag)){
match=i; //如果连接池中包含conn所描述的连接,则返回其下标,若无,则返回-1。
break;
}
}
return match;
}
// freeConnection(conn)方法用于将conn是释放,返回到连接池中供其他连接所使用。
public String freeConnection(Connection conn){
String res="";
int thisconn=idOfConnection(conn);
if(thisconn>=0){
connStatus[thisconn]=0; //若此连接有唯一标识,则利用其下标,将其状态改为空闲。
res="freed"+conn.toString();
}else{
System.out.println("---->Could not free connection!!!"+"Try to close if directly");
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return res;
}
// 此方法用于返回某连接的寿命。
public long getAge(Connection conn){
int thisconn=idOfConnection(conn);
return System.currentTimeMillis()-connLockTime[thisconn];
}
//此方法用于关闭后台线程,并在关闭millis时间后断开所有的连接
public void destroy(int millis)throws SQLException{
available=false;
runner.interrupt();
try {
runner.join(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long startTime=System.currentTimeMillis();
int useCount;
while((useCount=getUseCount())>0&&System.currentTimeMillis()-startTime<=millis){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 用一个循环,使得当前时间与方法开始调用的时间之差大于指定的millis之后,关闭所有连接。
for(int i=0;i<currConnections;i++){
connPool[i].close();
}
if(useCount>0){
throw new SQLException();
}
}
//默认销毁方法,millis值为10秒
public void destroy(){
try {
destroy(10000);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//返回正在被使用的连接数。
public int getUseCount(){
int useCount=0;
synchronized(connStatus){
for(int i=0;i<currConnections;i++){
if(connStatus[i]>0){
useCount++;
}
}
}
return useCount;
}
//返回动态连接池中现有的连接数
public int getSize(){
return currConnections;
}
}//end class
连接代码一般是jdbc:sqlserver://localhost:1433;DatabaseName=[name]。