java 連接池類

package com.demo.db;

import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;

public class DBConnectionManager {
static private DBConnectionManager instance; // 唯一實例

static private int clients;

private Vector drivers = new Vector();

private Hashtable pools = new Hashtable();

/**
* 將文本信息在後臺打印出來
*/
private void log(String msg) {
   System.out.println(new Date() + ": " + msg);
}

/**
* 返回唯一實例.如果是第一次調用此方法,則創建實例
*
* @return DBConnectionManager 唯一實例
*/
static synchronized public DBConnectionManager getInstance() {
   if (instance == null) {
    instance = new DBConnectionManager();
   }
   clients++;
   return instance;
}

/**
* 建構函數私有以防止其它對象創建本類實例
*/
private DBConnectionManager() {
   init();
}

/**
* 將連接對象返回給由名字指定的連接池
*
* @param name
*            在屬性文件中定義的連接池名字
* @param con
*            連接對象
*/
public void freeConnection(String name, Connection con) {
   DBConnectionPool pool = (DBConnectionPool) pools.get(name);
   if (pool != null) {
    pool.freeConnection(con);
   }
}

/**
* 獲得一個可用的(空閒的)連接.如果沒有可用連接,且已有連接數小於最大連接數 限制,則創建並返回新連接
*
* @param name
*            在屬性文件中定義的連接池名字
* @return Connection 可用連接或null
*/
public Connection getConnection(String name) {
   DBConnectionPool pool = (DBConnectionPool) pools.get(name);
   if (pool != null) {
    return pool.getConnection();
   }
   return null;
}

/**
* 獲得一個可用連接.若沒有可用連接,且已有連接數小於最大連接數限制, 則創建並返回新連接.否則,在指定的時間內等待其它線程釋放連接.
*
* @param name
*            連接池名字
* @param time
*            以毫秒計的等待時間
* @return Connection 可用連接或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("無法撤銷下列JDBC驅動程序的註冊: " + driver.getClass().getName());
    }
   }
}

/**
* 根據指定屬性創建連接池實例.
*
* @param props
*            連接池屬性
*/
private void createPools(Properties props) {
   Enumeration propNames = props.propertyNames();
   while (propNames.hasMoreElements()) {
    String name = (String) propNames.nextElement();
    if (name.endsWith(".url"))
    {
     String poolName = "sqlserver";
     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("/YYZL_db.properties");
   Properties dbProps = new Properties();
   try {
    dbProps.load(is);
   } catch (Exception e) {
    log("不能讀取屬性文件.請確保db.properties在CLASSPATH指定的路徑中");
    return;
   }
   loadDrivers(dbProps);
   createPools(dbProps);
}

/**
* 裝載和註冊所有JDBC驅動程序
*
* @param props
*            屬性
*/
private void loadDrivers(Properties props) {
   String driverClasses = props.getProperty("driver");
   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("成功註冊JDBC驅動程序" + driverClassName);
    } catch (Exception e) {
     log("無法註冊JDBC驅動程序: " + driverClassName + ", 錯誤: " + e);
    }
   }
}
/**
* 此內部類定義了一個連接池.它能夠根據要求創建新連接,直到預定的最大連接數爲止.在返回連接給客戶程序之前,它能夠驗證連接的有效性.
*/
class DBConnectionPool {
   private int userCount;

   private Vector freeConnections = new Vector();

   private int maxConn;

   private String name;

   private String password;

   private String URL;

   private String user;

//   private String databaseUrl;

   /**
   * 創建新的連接池
   *
   * @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);
    userCount--;
    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 || userCount < maxConn) {
     con = newConnection();
    }
    if (con != null) {
     userCount++;
    }
    return con;
   }

   /**
   * 從連接池獲取可用連接.可以指定客戶程序能夠等待的最長時間 參見前一個getConnection()方法.
   *
   * @param timeout
   *            以毫秒計的等待時間限制
   */
   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) {
      // 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("無法關閉連接池" + 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("無法創建下列URL的連接: " + URL);
     return null;
    }
    return con;
   }

}
}

 

 

 

package com.demo.db;

import java.sql.*;
public class DBConnect {
  private Connection conn = null;

  private Statement stmt = null;

  private PreparedStatement prepstmt = null;

  private DBConnectionManager dcm = null;

  void init() {
     dcm = DBConnectionManager.getInstance();
     conn = dcm.getConnection("mysql");
  }

  /**
  * 構造數據庫的連接和訪問類
  */
  public DBConnect() throws Exception {
     init();
     stmt = conn.createStatement();
  }

  public DBConnect(int resultSetType, int resultSetConcurrency)
      throws Exception {
     init();
     stmt = conn.createStatement(resultSetType, resultSetConcurrency);
  }

  /**
  * 構造數據庫的連接和訪問類 預編譯SQL語句
  *
  * @param sql
  *            SQL語句
  */
  public DBConnect(String sql) throws Exception {
     init();
     this.prepareStatement(sql);
  }

  public DBConnect(String sql, int resultSetType, int resultSetConcurrency)
      throws Exception {
     init();
     this.prepareStatement(sql, resultSetType, resultSetConcurrency);
  }

  /**
  * 返回連接
  *
  * @return Connection 連接
  */
  public Connection getConnection() {
     return conn;
  }

  /**
  * PreparedStatement
  *
  * @param sql 預設SQL語句
  */
  public void prepareStatement(String sql) throws SQLException {
     prepstmt = conn.prepareStatement(sql);
  }

  public void prepareStatement(String sql, int resultSetType,
      int resultSetConcurrency) throws SQLException {
     prepstmt = conn.prepareStatement(sql, resultSetType,
       resultSetConcurrency);
  }

  /**
  * 設置對應值
  *
  * @param index
  *            參數索引
  * @param value
  *            對應值
  */
  public void setString(int index, String value) throws SQLException {
     prepstmt.setString(index, value);
  }

  public void setInt(int index, int value) throws SQLException {
     prepstmt.setInt(index, value);
  }

  public void setBoolean(int index, boolean value) throws SQLException {
     prepstmt.setBoolean(index, value);
  }

  public void setDate(int index, Date value) throws SQLException {
     prepstmt.setDate(index, value);
  }

  public void setTimestamp(int index, Timestamp value) throws SQLException {
     prepstmt.setTimestamp(index, value);
  }

  public void setLong(int index, long value) throws SQLException {
     prepstmt.setLong(index, value);
  }

  public void setFloat(int index, float value) throws SQLException {
     prepstmt.setFloat(index, value);
  }

  public void setBytes(int index, byte[] value) throws SQLException {
     prepstmt.setBytes(index, value);
  }

  public void clearParameters() throws SQLException {
     prepstmt.clearParameters();
     prepstmt = null;
  }

  /**
  * 返回預設狀態
  */
  public PreparedStatement getPreparedStatement() {
     return prepstmt;
  }

  /**
  * 返回狀態
  *
  * @return Statement 狀態
  */
  public Statement getStatement() {
     return stmt;
  }

  /**
  * 執行SQL語句返回字段集
  *
  * @param sql
  *            SQL語句
  * @return ResultSet 字段集
  */
  public ResultSet executeQuery(String sql) throws SQLException {
     if (stmt != null) {
      return stmt.executeQuery(sql);
     } else
      return null;
  }

  public ResultSet executeQuery() throws SQLException {
     if (prepstmt != null) {
      return prepstmt.executeQuery();
     } else
      return null;
  }

  /**
  * 執行SQL語句
  *
  * @param sql
  *            SQL語句
  */
  public void executeUpdate(String sql) throws SQLException {
     if (stmt != null)
      stmt.executeUpdate(sql);
  }

  public void executeUpdate() throws SQLException {
     if (prepstmt != null)
      prepstmt.executeUpdate();
  }

  /**
  * 關閉連接
  */
  public void close() throws Exception {
     if (stmt != null) {
      stmt.close();
      stmt = null;
     }
     if (prepstmt != null) {
      prepstmt.close();
      prepstmt = null;
     }
     if (conn != null) {

      dcm.freeConnection("mysql", conn);

     }

  }
  }

//屬性文件

db.properties

 

driver=com.mysql.jdbc.Driver 
mysql.url=jdbc:mysql://192.168.23.176:3306/YYZL?useUnicode=true&characterEncoding=utf8
mysql.user=root
mysql.password=123456
mysql.maxconn=2000

發佈了21 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章