亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java實現數據庫連接池的方法

2019-11-26 15:04:57
字體:
來源:轉載
供稿:網友

本文實例講述了Java實現數據庫連接池的方法。分享給大家供大家參考。具體如下:

package com.kyo.connection;import java.sql.Connection;import java.sql.DatabaseMetaData;import java.sql.Driver;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;import java.util.Enumeration;import java.util.Vector;public class ConnectionPool {  private ConnectionParam param;  private String testTable = "";  // 測試連接是否可用的測試表名,默認沒有測試表  private Vector connections = null;  // 存放連接池中數據庫連接的向量 , 初始時為  // null,它中存放的對象為PooledConnection 型  public void setParam(ConnectionParam param) {    this.param = param;  }  public ConnectionParam getParam() {    return param;  }  /**   * 構造函數   *    * @param param   */  public ConnectionPool(ConnectionParam param) {    this.param = param;  }  /**   *    * 獲取測試數據庫表的名字   *    * @return 測試數據庫表的名字   */  public String getTestTable() {    return this.testTable;  }  /**   *    * 設置測試表的名字   *    * @param testTable   *      String 測試表的名字   */  public void setTestTable(String testTable) {    this.testTable = testTable;  }  /**   * 創建一個數據庫連接池,連接池中的可用連接的數量采用類成員 initialConnections 中設置的值   */  public synchronized void createPool() throws Exception {    // 確保連接池沒有創建    // 如果連接池己經創建了,保存連接的向量 connections 不會為空    if (connections != null) {      return; // 如果己經創建,則返回    }    // 實例化 JDBC Driver 中指定的驅動類實例    Driver driver = (Driver) (Class.forName(this.param.getDriver())        .newInstance());    DriverManager.registerDriver(driver); // 注冊 JDBC 驅動程序    // 創建保存連接的向量 , 初始時有 0 個元素    connections = new Vector();    // 根據 initialConnections 中設置的值,創建連接。    createConnections(this.param.getMinConnection());    System.out.println(" 數據庫連接池創建成功! ");  }  /**   *    * 創建由 numConnections 指定數目的數據庫連接 , 并把這些連接 放入 connections 向量中   *    * @param numConnections   *      要創建的數據庫連接的數目   */  private void createConnections(int numConnections) throws SQLException {    // 循環創建指定數目的數據庫連接    for (int x = 0; x < numConnections; x++) {      // 是否連接池中的數據庫連接的數量己經達到最大?最大值由類成員 maxConnections,指出,如果 maxConnections      // 為 0 或負數,表示連接數量沒有限制。      // 如果連接數己經達到最大,即退出。      if (this.param.getMaxConnection() > 0          && this.connections.size() >= this.param.getMaxConnection()) {        break;      }      // add a new PooledConnection object to connections vector      // 增加一個連接到連接池中(向量 connections 中)      try {        connections.addElement(new PooledConnection(newConnection()));      } catch (SQLException e) {        System.out.println(" 創建數據庫連接失敗! " + e.getMessage());        throw new SQLException();      }      System.out.println(" 數據庫連接己創建 ......");    }  }  /**   *    * 創建一個新的數據庫連接并返回它   *    * @return 返回一個新創建的數據庫連接   */  private Connection newConnection() throws SQLException {    // 創建一個數據庫連接    Connection conn = DriverManager.getConnection(this.param.getUrl(),        this.param.getUser(), this.param.getPassword());    // 如果這是第一次創建數據庫連接,即檢查數據庫,獲得此數據庫允許支持的    // 最大客戶連接數目    // connections.size()==0 表示目前沒有連接己被創建    if (connections.size() == 0) {      DatabaseMetaData metaData = conn.getMetaData();      int driverMaxConnections = metaData.getMaxConnections();      // 數據庫返回的 driverMaxConnections 若為 0 ,表示此數據庫沒有最大      // 連接限制,或數據庫的最大連接限制不知道      // driverMaxConnections 為返回的一個整數,表示此數據庫允許客戶連接的數 目      // 如果連接池中設置的最大連接數量大于數據庫允許的連接數目 , 則置連接池 的最大      // 連接數目為數據庫允許的最大數目      if (driverMaxConnections > 0          && this.param.getMaxConnection() > driverMaxConnections) {        this.param.setMaxConnection(driverMaxConnections);      }    }    return conn; // 返回創建的新的數據庫連接  }  /**   *    * 通過調用 getFreeConnection() 函數返回一個可用的數據庫連接 ,   *    * 如果當前沒有可用的數據庫連接,并且更多的數據庫連接不能創   *    * 建(如連接池大小的限制),此函數等待一會再嘗試獲取。   *    * @return 返回一個可用的數據庫連接對象   */  public synchronized Connection getConnection() throws SQLException {    // 確保連接池己被創建    if (connections == null) {      return null; // 連接池還沒創建,則返回 null    }    Connection conn = getFreeConnection(); // 獲得一個可用的數據庫連接    // 如果目前沒有可以使用的連接,即所有的連接都在使用中    while (conn == null) {      // 等一會再試      wait(250);      conn = getFreeConnection(); // 重新再試,直到獲得可用的連接,如果      // getFreeConnection() 返回的為 null      // 則表明創建一批連接后也不可獲得可用連接    }    return conn;// 返回獲得的可用的連接  }  /**   *    * 本函數從連接池向量 connections 中返回一個可用的的數據庫連接,如果   *    * 當前沒有可用的數據庫連接,本函數則根據 incrementalConnections 設置   *    * 的值創建幾個數據庫連接,并放入連接池中。   *    * 如果創建后,所有的連接仍都在使用中,則返回 null   *    * @return 返回一個可用的數據庫連接   */  private Connection getFreeConnection() throws SQLException {    // 從連接池中獲得一個可用的數據庫連接    Connection conn = findFreeConnection();    if (conn == null) {      // 如果目前連接池中沒有可用的連接      // 創建一些連接      createConnections(this.param.getIncrementalConnections());      // 重新從池中查找是否有可用連接      conn = findFreeConnection();      if (conn == null) {        // 如果創建連接后仍獲得不到可用的連接,則返回 null        return null;      }    }    return conn;  }  /**   *    * 查找連接池中所有的連接,查找一個可用的數據庫連接,   *    * 如果沒有可用的連接,返回 null   *    * @return 返回一個可用的數據庫連接   */  private Connection findFreeConnection() throws SQLException {    Connection conn = null;    PooledConnection pConn = null;    // 獲得連接池向量中所有的對象    Enumeration enumerate = connections.elements();    // 遍歷所有的對象,看是否有可用的連接    while (enumerate.hasMoreElements()) {      pConn = (PooledConnection) enumerate.nextElement();      if (!pConn.isBusy()) {        // 如果此對象不忙,則獲得它的數據庫連接并把它設為忙        conn = pConn.getConnection();        pConn.setBusy(true);        // 測試此連接是否可用        if (!testConnection(conn)) {          // 如果此連接不可再用了,則創建一個新的連接,          // 并替換此不可用的連接對象,如果創建失敗,返回 null          try {            conn = newConnection();          } catch (SQLException e) {            System.out.println(" 創建數據庫連接失?。?" + e.getMessage());            return null;          }          pConn.setConnection(conn);        }        break; // 己經找到一個可用的連接,退出      }    }    return conn;// 返回找到到的可用連接  }  /**   *    * 測試一個連接是否可用,如果不可用,關掉它并返回 false   *    * 否則可用返回 true   *    *    *    * @param conn   *      需要測試的數據庫連接   *    * @return 返回 true 表示此連接可用, false 表示不可用   */  private boolean testConnection(Connection conn) {    try {      // 判斷測試表是否存在      if (testTable.equals("")) {        // 如果測試表為空,試著使用此連接的 setAutoCommit() 方法        // 來判斷連接否可用(此方法只在部分數據庫可用,如果不可用 ,        // 拋出異常)。注意:使用測試表的方法更可靠        conn.setAutoCommit(true);      } else {        // 有測試表的時候使用測試表測試        // check if this connection is valid        Statement stmt = conn.createStatement();        stmt.execute("select count(*) from " + testTable);      }    } catch (SQLException e) {      // 上面拋出異常,此連接己不可用,關閉它,并返回 false;      closeConnection(conn);      return false;    }    // 連接可用,返回 true    return true;  }  /**   *    * 此函數返回一個數據庫連接到連接池中,并把此連接置為空閑。   *    * 所有使用連接池獲得的數據庫連接均應在不使用此連接時返回它。   *    * @param 需返回到連接池中的連接對象   */  public void returnConnection(Connection conn) {    // 確保連接池存在,如果連接沒有創建(不存在),直接返回    if (connections == null) {      System.out.println(" 連接池不存在,無法返回此連接到連接池中 !");      return;    }    PooledConnection pConn = null;    Enumeration enumerate = connections.elements();    // 遍歷連接池中的所有連接,找到這個要返回的連接對象    while (enumerate.hasMoreElements()) {      pConn = (PooledConnection) enumerate.nextElement();      // 先找到連接池中的要返回的連接對象      if (conn == pConn.getConnection()) {        // 找到了 , 設置此連接為空閑狀態        pConn.setBusy(false);        break;      }    }  }  /**   *    * 刷新連接池中所有的連接對象   *    *    */  public synchronized void refreshConnections() throws SQLException {    // 確保連接池己創新存在    if (connections == null) {      System.out.println(" 連接池不存在,無法刷新 !");      return;    }    PooledConnection pConn = null;    Enumeration enumerate = connections.elements();    while (enumerate.hasMoreElements()) {      // 獲得一個連接對象      pConn = (PooledConnection) enumerate.nextElement();      // 如果對象忙則等 5 秒 ,5 秒后直接刷新      if (pConn.isBusy()) {        wait(5000); // 等 5 秒      }      // 關閉此連接,用一個新的連接代替它。      closeConnection(pConn.getConnection());      pConn.setConnection(newConnection());      pConn.setBusy(false);    }  }  /**   *    * 關閉連接池中所有的連接,并清空連接池。   */  public synchronized void closeConnectionPool() throws SQLException {    // 確保連接池存在,如果不存在,返回    if (connections == null) {      System.out.println(" 連接池不存在,無法關閉 !");      return;    }    PooledConnection pConn = null;    Enumeration enumerate = connections.elements();    while (enumerate.hasMoreElements()) {      pConn = (PooledConnection) enumerate.nextElement();      // 如果忙,等 5 秒      if (pConn.isBusy()) {        wait(5000); // 等 5 秒      }      // 5 秒后直接關閉它      closeConnection(pConn.getConnection());      // 從連接池向量中刪除它      connections.removeElement(pConn);    }    // 置連接池為空    connections = null;  }  /**   *    * 關閉一個數據庫連接   *    * @param 需要關閉的數據庫連接   */  private void closeConnection(Connection conn) {    try {      conn.close();    } catch (SQLException e) {      System.out.println(" 關閉數據庫連接出錯: " + e.getMessage());    }  }  /**   *    * 使程序等待給定的毫秒數   *    * @param 給定的毫秒數   */  private void wait(int mSeconds) {    try {      Thread.sleep(mSeconds);    } catch (InterruptedException e) {    }  }  /**   *    * 內部使用的用于保存連接池中連接對象的類 此類中有兩個成員,一個是數據庫的連接,另一個是指示此連接是否 正在使用的標志。   */  class PooledConnection {    Connection connection = null;// 數據庫連接    boolean busy = false; // 此連接是否正在使用的標志,默認沒有正在使用    // 構造函數,根據一個 Connection 構告一個 PooledConnection 對象    public PooledConnection(Connection connection) {      this.connection = connection;    }    // 返回此對象中的連接    public Connection getConnection() {      return connection;    }    // 設置此對象的,連接    public void setConnection(Connection connection) {      this.connection = connection;    }    // 獲得對象連接是否忙    public boolean isBusy() {      return busy;    }    // 設置對象的連接正在忙    public void setBusy(boolean busy) {      this.busy = busy;    }  }}

希望本文所述對大家的java程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91在线直播亚洲| 最近2019中文字幕大全第二页| 欧美综合激情网| 亚洲视频在线看| 欧美中文字幕视频在线观看| 91精品综合久久久久久五月天| 日本国产精品视频| 亚洲第一在线视频| www亚洲欧美| 国产v综合ⅴ日韩v欧美大片| 久久精品99国产精品酒店日本| 成人黄在线观看| 国产福利视频一区二区| 日韩在线中文字| 亚洲国产日韩精品在线| 久久99精品视频一区97| 欧美在线www| 欧美精品免费在线观看| 久久久久久尹人网香蕉| 青青草国产精品一区二区| 午夜剧场成人观在线视频免费观看| 精品亚洲一区二区三区四区五区| 日韩有码在线观看| 亚洲级视频在线观看免费1级| 欧美裸体xxxx极品少妇软件| 亚洲精品久久久久久久久久久久久| 亚洲欧美另类中文字幕| 日韩av在线导航| 在线播放日韩精品| 97精品国产aⅴ7777| 中文字幕日韩精品有码视频| 久久99久久99精品中文字幕| 亚洲午夜色婷婷在线| 日韩亚洲欧美中文高清在线| 国产精品美女www爽爽爽视频| 不卡在线观看电视剧完整版| 亚洲综合一区二区不卡| 成人性生交大片免费观看嘿嘿视频| 国产不卡精品视男人的天堂| 亚洲成人精品在线| 川上优av一区二区线观看| 久久不射热爱视频精品| 美女久久久久久久久久久| 国内外成人免费激情在线视频| 欧美片一区二区三区| 欧美高清在线视频观看不卡| 成人午夜小视频| 欧美日韩亚洲视频| 国产成人一区二区三区| 美女撒尿一区二区三区| 中文字幕精品网| 日韩欧美中文第一页| 日韩av手机在线| 97在线观看视频国产| 亚洲天堂av网| 精品久久久国产| 欧美与欧洲交xxxx免费观看| 日韩在线视频国产| 日韩免费av片在线观看| 久久综合久中文字幕青草| 国产精品第1页| 精品欧美激情精品一区| 日韩高清av一区二区三区| 亚洲国产私拍精品国模在线观看| 疯狂做受xxxx欧美肥白少妇| 亚洲石原莉奈一区二区在线观看| 久久久久久久成人| 精品亚洲一区二区三区在线播放| 欧美第一黄网免费网站| 亚洲新中文字幕| 精品动漫一区二区| 在线中文字幕日韩| 97在线观看免费| 国产综合色香蕉精品| 欧美激情a在线| 国产精品久久久久久亚洲调教| 最近2019中文字幕第三页视频| 精品亚洲夜色av98在线观看| 国产精品毛片a∨一区二区三区|国| 亚洲第一网中文字幕| 欧美超级免费视 在线| 久久精品视频播放| 色爱av美腿丝袜综合粉嫩av| 91丝袜美腿美女视频网站| 国产深夜精品福利| 亚洲国产成人精品女人久久久| 97在线免费观看| 亚洲成人在线网| 国产精品日韩欧美| 亚洲有声小说3d| 人人澡人人澡人人看欧美| 久久久久国色av免费观看性色| 91国在线精品国内播放| 亚洲爱爱爱爱爱| 久久久国产精彩视频美女艺术照福利| 国产精品久久久久久搜索| 中文字幕无线精品亚洲乱码一区| 中文字幕日本欧美| 国产欧美日韩专区发布| 亚洲成人a级网| 日韩成人中文字幕| 亚洲成年人影院在线| 欧美性猛交xxxx久久久| 69国产精品成人在线播放| 国产福利视频一区| 国产成+人+综合+亚洲欧洲| 亚洲自拍av在线| 久久精品一区中文字幕| 国产精品第七十二页| 国产成人鲁鲁免费视频a| 久久精品亚洲94久久精品| 久久躁狠狠躁夜夜爽| 自拍偷拍亚洲一区| 欧美人在线观看| 色噜噜亚洲精品中文字幕| 91禁国产网站| 欧美大片在线看| 国产亚洲精品久久久久久777| 91在线观看欧美日韩| 美女扒开尿口让男人操亚洲视频网站| 亚洲第一精品福利| 亚洲欧美日韩国产精品| 午夜精品一区二区三区在线播放| 久久天堂av综合合色| 欧美午夜影院在线视频| 成人中文字幕在线观看| 久久成人精品一区二区三区| 久久久免费在线观看| 国产精品99久久久久久久久| 国产成人精品综合| 一区二区三区黄色| 色香阁99久久精品久久久| 伊人一区二区三区久久精品| 亚洲色图欧美制服丝袜另类第一页| 91av在线精品| 91av视频在线播放| 欧美在线国产精品| 久久久久久国产免费| 91网在线免费观看| 国产偷国产偷亚洲清高网站| 国产精品视频久久久| 亚洲一区二区久久| 国产精品视频久久| 欧美日韩福利在线观看| 国产精品69精品一区二区三区| 午夜精品福利视频| 久久人人爽亚洲精品天堂| 亚洲欧美日韩国产精品| 国产欧美中文字幕| 精品久久中文字幕| 亚洲欧美国产制服动漫| 7777免费精品视频| 91久久久久久| 中文字幕在线精品| 在线精品视频视频中文字幕| 亚洲精品欧美日韩专区| 成人免费网站在线观看| 正在播放亚洲1区| 尤物99国产成人精品视频| 午夜精品久久久久久99热| 欧美国产视频日韩| 久久久久久久久久久久av| 国产视频999| 亚洲日本中文字幕免费在线不卡|