📄 dbconnectionmanager.java
字号:
try{
//如果文件大于5M,就把原log文件名+1,然后另立文件
File logFile=new File(logFileName);
if(logFile!=null && logFile.exists() && logFile.length() > 5*1024*1024 ) { //如果文件大于5M
String filePre=logFileName.substring(0,logFileName.indexOf("."));
File f1;
for(int i=1;i>0;i++){
f1=new File(filePre+String.valueOf(i)+".txt");
if(f1.exists())
continue;
else{
logFile.renameTo(new File(filePre+String.valueOf(i)+".txt"));
logFile=new File(logFileName);
logFW = new FileWriter(logFileName,true); //false 覆盖原有文件
logPW = new PrintWriter(logFW);
break;
}
}
}
if(logPW == null){
logFile=new File(logFileName);
logFW = new FileWriter(logFileName,true); //false 覆盖原有文件
logPW = new PrintWriter(logFW);
}
logPW.print(new java.util.Date()+" "+msg);
logPW.print("\r\n");
logPW.flush();
}catch(Exception e){System.out.println("writeLog:"+e);}
}
/**
* 将文本信息与异常写入日志文件
*/
private void log(Throwable e, String msg) {
//log.println(new Date() + ": " + msg);
// e.printStackTrace(log);
log(e.getMessage()+" "+msg);
}
/**
* 返回连接状态信息,用在页面中显示
*/
public String toString(String name) {
String status="当前共有连接池:"+String.valueOf(pools.size())+"个";
status +="<br>接池创建的连接总数为:"+String.valueOf(connectionCounter)+"次";
status +="<br>连接池被访问的总数为:"+String.valueOf(clients)+"次";
DBConnectionPool pool = (DBConnectionPool) pools.get(name);
status +="<br>"+pool.toString();
return status;
}
/**
* 获取连接池的空闲连接数
*/
public int getNumberOfFreeConnections(String poolName){
DBConnectionPool pool = (DBConnectionPool) pools.get(poolName);
return pool.getNumberOfFreeConnections();
}
/***************连接池类*************************************************/
/**
* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
* 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*/
class DBConnectionPool {
private int checkedOut;
private Vector freeConnections = new Vector();
private Vector freeConnectionIdleTime = new Vector(); //新增 记录空闲连接的上一次调用时间
//private Vector inUseConnectionTime = new Vector(); //正在使用的连接所占用的时间
private int maxIdleTime = 30000; //空闲连接的最长空闲时间 超过该时间将关闭该连接 单位:ms毫秒
//private int maxInUseTime = 30000;
private int maxConn;
private String name;
private String user;
private String pass;
private String URL;
String sql="SET NAMES \"iso-8859-1\"";
//private String dbInfo;
private int connectionWaitTimes=0;
public void setURL(String URL){
this.URL = URL;
}
/**
* 创建新的连接池
*
* @param name 连接池名字
* @param URL 数据库的JDBC URL
* @param dbInfo 数据库连接信息
* @param maxConn 此连接池允许建立的最大连接数
*/
//public DBConnectionPool(String name, String URL, String dbInfo, int maxConn) {
public DBConnectionPool(String name, String URL, String user,String pass, int maxConn) {
this.name = name;
this.URL = URL;
//this.dbInfo = dbInfo;
this.user=user;
this.pass=pass;
this.maxConn = maxConn;
}
/**
*释放超过最长空闲连接时间的连接(这些连接不稳定)
*
*/
public synchronized void releaseMaxIdleConnections(){
try{
long idleTime=0;
Connection con = null;
for(int i=0;i<freeConnections.size();i++){
idleTime = System.currentTimeMillis()-((Long)freeConnectionIdleTime.elementAt(i)).longValue();
if(idleTime >= maxIdleTime){
con = (Connection)freeConnections.elementAt(i);
if(con!=null && !con.isClosed()){
con.close();
con = null;
}
else if(con!=null)
con=null;
freeConnections.removeElementAt(i);
freeConnectionIdleTime.removeElementAt(i);
log("从连接池" + name+"删除一个过期("+String.valueOf(idleTime/1000)+"秒)连接");
}
}
}catch(Exception e){}
}
/**
* 将不再使用的连接返回给连接池
*
* @param con 客户程序释放的连接
*/
public synchronized void freeConnection(Connection con) {
// 将指定连接加入到向量末尾
freeConnections.addElement(con);
freeConnectionIdleTime.addElement(new Long(System.currentTimeMillis()));
checkedOut--;
notifyAll();
}
/**
* 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
* 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
* 然后递归调用自己以尝试新的可用连接.
*/
public synchronized Connection getConnection() {
releaseMaxIdleConnections();
Connection con = null;
if (freeConnections.size() > 0) {
// 获取向量中第一个可用连接
con = (Connection) freeConnections.firstElement();
freeConnections.removeElementAt(0);
freeConnectionIdleTime.removeElementAt(0);
try {
if (con.isClosed()) {
log("从连接池" + name+"删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
}
}
catch (SQLException e) {
log("从连接池" + name+"删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
}
}
else if (maxConn == 0 || checkedOut < maxConn) {
con = newConnection();
}
if (con != null) {
checkedOut++;
}
else{
log("获得一个空连接,原因是最大连接数"+checkedOut+"超出额定最大连接数"+maxConn+" 创建一个额外的连接");
con = newConnection();
checkedOut++;
}
return con;
}
/**
* 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
* 参见前一个getConnection()方法.
*
* @param timeout 以毫秒计的等待时间限制
*/
public synchronized Connection getConnection(long timeout) {
long startTime = new Date().getTime();
Connection con;
connectionWaitTimes++;
log("延时("+String.valueOf(timeout)+"秒)获取连接方法被调用");
while ((con = getConnection()) == null) {
try {
wait(timeout);
}
catch (InterruptedException e) {}
if ((new Date().getTime() - startTime) >= timeout) {
// wait()返回的原因是超时
log("延时("+String.valueOf(timeout)+"秒)获取连接方法被调用失败:超时");
return null;
}
}
log("延时("+String.valueOf(timeout)+"秒)获取连接方法被调用成功。");
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();
}
/**
* 创建新的连接
*/
private Connection newConnection() {
Connection con = null;
try {
//con = DriverManager.getConnection(URL+dbInfo);
con = DriverManager.getConnection(URL,user,pass);
//con.setAutoCommit(false);
connectionCounter++;
log("连接池" + name+"创建一个(第"+connectionCounter+"个)新的连接");
}
catch (SQLException e) {
log(e, " 无法创建下列URL的连接: " + URL);
return null;
}
/**
if(con!=null){
try{
PreparedStatement select_stm=con.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
select_stm.executeQuery();
}catch(Exception e){log(e, sql); }
}
**/
return con;
}
/**
*
*/
public String toString(){
String status="连接池"+name+"的空闲连接数为:"+String.valueOf(freeConnections.size());
status +="<br>连接池"+name+"正在使用的连接数为:" +String.valueOf(checkedOut);
status +="<br>从连接池"+name+"获取连接需要排队的次数为:" +String.valueOf(connectionWaitTimes);
status +="<br>连接池"+name+"最大连接数为:" +String.valueOf(maxConn);
return status;
}
public int getNumberOfFreeConnections(){
return freeConnections.size();
}
}//class DBConnectionPool
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -