熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

連接池用法

2022-06-13   來源: JSP教程 

  JDBC
  Java Servlet作為首選的服務器端數據處理技術正在迅速取代CGI腳本Servlet超越CGI的優勢之一在於不僅多個請求可以共享公用資源而且還可以在不同用戶請求之間保留持續數據本文介紹一種充分發揮該特色的實用技術即數據庫連接池
  
  一實現連接池的意義
  
  動態Web站點往往用數據庫存儲的信息生成Web頁面每一個頁面請求導致一次數據庫訪問連接數據庫不僅要開銷一定的通訊和內存資源還必須完成用戶驗證安全上下文配置這類任務因而往往成為最為耗時的操作當然實際的連接時間開銷千變萬化秒延遲並非不常見如果某個基於數據庫的Web應用只需建立一次初始連接不同頁面請求能夠共享同一連接就能獲得顯著的性能改善
  Servlet是一個Java類Servlet引擎(它可能是Web服務軟件的一部分也可能是一個獨立的附加模塊)在系統啟動或Servlet第一次被請求時將該類裝入Java虛擬機並創建它的一個實例不同用戶請求由同一Servlet實例的多個獨立線程處理那些要求在不同請求之間持續有效的數據既可以用Servlet的實例變量來保存也可以保存在獨立的輔助對象中
  用JDBC訪問數據庫首先要創建與數據庫之間的連接獲得一個連接對象(Connection)由連接對象提供執行SQL語句的方法本文介紹的數據庫連接池包括一個管理類DBConnectionManager負責提供與多個連接池對象(DBConnectionPool類)之間的接口每一個連接池對象管理一組JDBC連接對象每一個連接對象可以被任意數量的Servlet共享
  類DBConnectionPool提供以下功能
  
  ) 從連接池獲取(或創建)可用連接
  ) 把連接返回給連接池
  ) 在系統關閉時釋放所有資源關閉所有連接
  
  此外 DBConnectionPool類還能夠處理無效連接(原來登記為可用的連接由於某種原因不再可用如超時通訊問題)並能夠限制連接池中的連接總數不超過某個預定值
  管理類DBConnectionManager用於管理多個連接池對象它提供以下功能
  
  ) 裝載和注冊JDBC驅動程序
  ) 根據在屬性文件中定義的屬性創建連接池對象
  ) 實現連接池名字與其實例之間的映射
  ) 跟蹤客戶程序對連接池的引用保證在最後一個客戶程序結束時安全地關閉所有連接池
  
  本文余下部分將詳細說明這兩個類最後給出一個示例演示Servlet使用連接池的一般過程
  
  二具體實現
  
  DBConnectionManagerjava程序清單如下
  
   import javaio*;
   import javasql*;
   import javautil*;
   import javautilDate;
  
   /**
   * 管理類DBConnectionManager支持對一個或多個由屬性文件定義的數據庫連接
   * 池的訪問客戶程序可以調用getInstance()方法訪問本類的唯一實例
   */
   public class DBConnectionManager {
   static private DBConnectionManager instance; // 唯一實例
   static private int clients;
  
   private Vector drivers = new Vector();
   private PrintWriter log;
   private Hashtable pools = new Hashtable();
  
   /**
   * 返回唯一實例如果是第一次調用此方法則創建實例
   *
   * @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) poolsget(name);
   if (pool != null) {
   poolfreeConnection(con);
   }
   }
  
   /**
   * 獲得一個可用的(空閒的)連接如果沒有可用連接且已有連接數小於最大連接數
   * 限制則創建並返回新連接
   *
   * @param name 在屬性文件中定義的連接池名字
   * @return Connection 可用連接或null
   */
   public Connection getConnection(String name) {
   DBConnectionPool pool = (DBConnectionPool) poolsget(name);
   if (pool != null) {
   return poolgetConnection();
   }
   return null;
   }
  
   /**
   * 獲得一個可用連接若沒有可用連接且已有連接數小於最大連接數限制
   * 則創建並返回新連接否則在指定的時間內等待其它線程釋放連接
   *
   * @param name 連接池名字
   * @param time 以毫秒計的等待時間
   * @return Connection 可用連接或null
   */
   public Connection getConnection(String name long time) {
   DBConnectionPool pool = (DBConnectionPool) poolsget(name);
   if (pool != null) {
   return poolgetConnection(time);
   }
   return null;
   }
  
   /**
   * 關閉所有連接撤銷驅動程序的注冊
   */
   public synchronized void release() {
   // 等待直到最後一個客戶程序調用
   if (clients != ) {
   return;
   }
  
   Enumeration allPools = poolselements();
   while (allPoolshasMoreElements()) {
   DBConnectionPool pool = (DBConnectionPool) allPoolsnextElement();
   poolrelease();
   }
   Enumeration allDrivers = driverselements();
   while (allDrivershasMoreElements()) {
   Driver driver = (Driver) allDriversnextElement();
   try {
   DriverManagerderegisterDriver(driver);
   log(撤銷JDBC驅動程序 + drivergetClass()getName()+的注冊);
   }
   catch (SQLException e) {
   log(e 無法撤銷下列JDBC驅動程序的注冊: + drivergetClass()getName());
   }
   }
   }
  
   /**
   * 根據指定屬性創建連接池實例
   *
   * @param props 連接池屬性
   */
   private void createPools(Properties props) {
   Enumeration propNames = propspropertyNames();
   while (propNameshasMoreElements()) {
   String name = (String) propNamesnextElement();
   if (nameendsWith(url)) {
   String poolName = namesubstring( namelastIndexOf());
   String url = propsgetProperty(poolName + url);
   if (url == null) {
   log(沒有為連接池 + poolName + 指定URL);
   continue;
   }
   String user = propsgetProperty(poolName + user);
   String password = propsgetProperty(poolName + password);
   String maxconn = propsgetProperty(poolName + maxconn );
   int max;
   try {
   max = IntegervalueOf(maxconn)intValue();
   }
   catch (NumberFormatException e) {
   log(錯誤的最大連接數限制: + maxconn + 連接池: + poolName);
   max = ;
   }
   DBConnectionPool pool =
   new DBConnectionPool(poolName url user password max);
   poolsput(poolName pool);
   log(成功創建連接池 + poolName);
   }
   }
   }
  
   /**
   * 讀取屬性完成初始化
   */
   private void init() {
   InputStream is = getClass()getResourceAsStream(/dbproperties);
   Properties dbProps = new Properties();
   try {
   dbPropsload(is);
   }
   catch (Exception e) {
   Systemerrprintln(不能讀取屬性文件 +
   請確保dbproperties在CLASSPATH指定的路徑中);
   return;
   }
   String logFile = dbPropsgetProperty(logfile DBConnectionManagerlog);
   try {
   log = new PrintWriter(new FileWriter(logFile true) true);
   }
   catch (I
From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19437.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.