数据库连接池

转载 2004年07月10日 17:27:00

完整程序 -> 数据库的连接池(经典的那种) 
软件名称: 数据库的连接池(经典的那种)
提交时间: 2002-06-08
作者: jewes
提交人: 本站提供 
相关网址: jewes.sharella.com 
点击次数: 4628 
package com.jewes;
import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;

//建立DBConnectionManager
public class DBConnectionManager
{static private DBConnectionManager instance;
 static private int clients;

 private Vector drivers=new Vector();
 private PrintWriter log;
 private Hashtable pools=new Hashtable();

 //返回唯一的实列
 static synchronized public DBConnectionManager getInstance()
{if(instance==null)
{instance=new DBConnectionManager();
  }
     clients++;
 return instance;
}
 
 //构造函数!
 private DBConnectionManager()
{init();
}
 //结束构造函数
 //释放一个连接
 public void freeConnection(String name,Connection con)
{DBConnectionPool pool=(DBConnectionPool)pools.get(name);
      if(pool!=null)
{pool.freeConnection(con);
    }
}
//结束释放一个连接

//取得一个连接
 public Connection getConnection(String name)
{DBConnectionPool pool=(DBConnectionPool)pools.get(name);
       if(pool!=null)
{return pool.getConnection();
}
      return null;
}

public Connection getConnection(String name,long time)
{DBConnectionPool pool=(DBConnectionPool)pools.get(name);
     if(pool!=null)
        {return pool.getConnection(time);
}
      return null;
}
//结束getconnection
//关闭所有连接
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());
}
}
}
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()
{InputStream is=getClass().getResourceAsStream("/db.properties");
     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);
}
     loadDriver(dbProps);
 createPools(dbProps);
}

private void loadDriver(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);
 log("成功注册驱动程序"+driverClassName);
}
catch(Exception e)
{log("无法注册驱动程序:"+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 checkOut;
 private Vector freeConnections=new Vector();
     private int maxconn;
 private String name;
 private String password;
 private String URL;
 private String user;
 
     public DBConnectionPool(String name,String URL,String user,String password,int maxconn)
{this.name=name;
     this.URL=URL;
 this.password=password;
   this.user=user;
 this.maxconn=maxconn;
    }
      public synchronized void freeConnection(Connection con)
{freeConnections.addElement(con);
     checkOut--;
 notifyAll();
}
     public synchronized Connection getConnection()
{Connection con=null;
        if(freeConnections.size()>0)
{con=(Connection)freeConnections.firstElement();
 freeConnections.removeElementAt(0);
 try
{if(con.isClosed())
{log("从连接池"+name+"删除一个连接");
         con=getConnection();
}
}
             catch(SQLException e)
{log("从连接池"+name+"删除一个连接");
con=getConnection();
}
}
else if(maxconn==0||checkOut<maxconn)
{con=newConnection();
}
if(con!=null)
{checkOut++;
}
return con;
}

       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)
{return null;
    }
}
return con;
}
   public 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,user,password);
    log("连接池"+name+"创建一个新的连接");
}
         catch(SQLException e)
{log(e,"无法创建下列URL的连接"+URL);
     return null;
    }
       return con;
}
}
}

数据库连接池的好处

对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况...
  • yzllz001
  • yzllz001
  • 2017年02月03日 11:30
  • 3788

三种数据库连接池的配置及使用(For JDBC)

三种开源数据源c3p0,DBCP以及Tomcat内置数据源(DBCP)的使用简介,
  • u012802702
  • u012802702
  • 2016年04月15日 09:26
  • 8984

Java常用数据库连接池【整理】

应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪...
  • qiuzhi__ke
  • qiuzhi__ke
  • 2015年12月08日 19:43
  • 1996

为什么要使用数据库连接池

对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况...
  • baidu_24256693
  • baidu_24256693
  • 2015年04月07日 23:48
  • 3170

数据库连接池的理解和使用

一、什么是数据库连接池? 官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。 ...
  • wenwen091100304
  • wenwen091100304
  • 2015年08月27日 20:49
  • 34574

java数据库连接池配置的几种方法

今天遇到了关于数据源连接池配置的问题,发现有很多种方式可以配置,现总结如下,希望对大家有所帮助:(已Mysql数据库为例) 一,Tomcat配置数据源: 方式一:在WebRoot下面建文件夹ME...
  • lx19860203
  • lx19860203
  • 2014年01月07日 10:12
  • 2224

三、配置数据库连接池

一、添加数据库包commons-dbcp依赖 pom.xml文件内容为:   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0...
  • mgfshut
  • mgfshut
  • 2016年11月02日 16:47
  • 935

java项目几种常见数据库连接池的使用比较

作者曾经主持以及经历的几个产品及项目中,包括了各种数据库及应用服务器,基本上几种常见的数据库连接池都用到了,根据使用的情况把这些连接池比较一下吧。 感觉在介绍之前有必要阐述一下连接池的几个概念,...
  • zf900901298
  • zf900901298
  • 2014年02月07日 14:41
  • 3860

几种常见数据库连接池的使用比较

感觉在介绍之前有必要阐述一下连接池的几个概念,有助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库...
  • u011088260
  • u011088260
  • 2016年11月23日 20:35
  • 2700

Spring 中数据源和数据库连接池配置的几种方法

原文地址:http://blog.csdn.net/liyangbing315/article/details/4730961 Spring 中数据源和数据库连接池配置的几种方法 ...
  • SengMay
  • SengMay
  • 2016年04月19日 17:41
  • 2128
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据库连接池
举报原因:
原因补充:

(最多只允许输入30个字)