posts - 189,comments - 115,trackbacks - 0
一个很不错的数据库连接池实现,备份之
 

一个很不错的数据库连接池实现,备份之

import java.sql.*;
import java.io.*;
import java.util.*;
public class DBConnectionManager {

  private static int clients = 0;
  private static DBConnectionManager instance;
  private Vector drivers = new Vector();
  private PrintWriter log;
  private Hashtable pools = new Hashtable();


  public DBConnectionManager() {
    init();
  }
  private void log(String msg) {
    log.println(new java.util.Date() + ": " + msg);
  }

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

  public static synchronized  DBConnectionManager getInstance() {
    if (instance == null) {
      instance = new DBConnectionManager();
    }
    clients++;
    return instance;
  }
  private void init() {
    InputStream is = getClass().getResourceAsStream("/db.properties");
    Properties dbProps = new Properties();
    try {
      dbProps.load(is);
    }
    catch (Exception e) {
        System.err.println("Can not read the properties file. " +
        "Make sure db.properties is in the CLASSPATH");
        return;
    }
    loadDrivers(dbProps);
    createPools(dbProps);
  }
  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;
  }
  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());
      }
    }
  }


/*
drivers=sun.jdbc.odbc.JdbcOdbcDriver jdbc.idbDriver

logfile=D:\\user\\src\\java\\DBConnectionManager\\log.txt

idb.url=jdbc:idb:c:\\local\\javawebserver1.1\\db\\db.prp

idb.maxconn=2

access.url=jdbc:odbc:demo

access.user=demo

access.password=demopw

*/
  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);
     //   Log.log("Registered JDBC driver " + driverClassName);
      }
      catch (Exception e) {
      //  Log.log("Can not register JDBC driver: " + driverClassName + ", Exception: " + e.toString()));
      }
    }
  }
  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.log("No URL specified for " + poolName);
          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.log("Invalid maxconn value " + maxconn + " for " +   poolName);
          max = 0;
        }
        DBConnectionPool pool =
          new DBConnectionPool(poolName, url, user, password, max);
        pools.put(poolName, pool);
      //  Log.log("Initialized pool " + poolName);
      }
    }
  }

  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) {
    // 将指定连接加入到向量末尾
      freeConnections.addElement(con);
      checkedOut--;
      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 || checkedOut < maxConn)
      {
        con = newConnection();
      }
      if (con != null) {
        checkedOut++;
      }
      return con;
    }

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

  /**
  * 创建新的连接
  */
    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;
    }
  }
}

posted on 2006-03-25 20:28 MEYE 阅读(335) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: