求一个STRUTS2 SQLSERVER2000的连接池的代码,最好有个例子

学无止境-逆流而上 2011-10-28 01:15:30
如题,网上找了很久,没找到,以前只用过JSP MYSQL的连接池,实在不想花时间去一个个试了-_-
...全文
215 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
C_c 2011-10-28
  • 打赏
  • 举报
回复
这是一种连接池的java代码,上面的注释我写的很清楚了。使用的时候直接给它的构造函数赋值就行了,驱动方面的代码baidu有的下,sqlserver的驱动代码一般是com.microsoft.sqlserver.jdbc.SQLServerDriver,
连接代码一般是jdbc:sqlserver://localhost:1433;DatabaseName=[name]。
C_c 2011-10-28
  • 打赏
  • 举报
回复
//下面该方法用于真正创建一个连接。
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
C_c 2011-10-28
  • 打赏
  • 举报
回复
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();
}
}



我嘞个去 2011-10-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ticmy 的回复:]
连接池不都是一样的用么?!
[/Quote]
对呀。
龙四 2011-10-28
  • 打赏
  • 举报
回复
连接池不都是一样的用么?!
良才2015 2011-10-28
  • 打赏
  • 举报
回复
最近也在转换,mark

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧