Java jdbc數據庫連接池總結


1. 引言

  近年來,隨着Internet/Intranet建網技術的飛速發展和在世界范圍內的迅速普及,計算機

  應用程序已從傳統的桌面應用轉到Web應用。基於B/S(Browser/Server)架構的3層開發模式逐漸取代C/S(Client/Server)架構的開發模式,成為開發企業級應用和電子商務普遍采用的技術。在Web應用開發的早期,主要使用的技術是CGIASPPHP等。之后,Sun公司推出了基於Java語言的Servlet+Jsp+JavaBean技術。相比傳統的開發技術,它具有跨平台﹑安全﹑有效﹑可移植等特性,這使其更便於使用和開發。

  Java應用程序訪問數據庫的基本原理

  在Java語言中,JDBC(Java DataBase Connection)是應用程序與數據庫溝通的橋梁,

  即Java語言通過JDBC技術訪問數據庫。JDBC是一種“開放”的方案,它為數據庫應用開發人員﹑數據庫前台工具開發人員提供了一種標准的應用程序設計接口,使開發人員可以用純Java語言編寫完整的數據庫應用程序。JDBC提供兩種API,分別是面向開發人員的API和面向底層的JDBC驅動程序API,底層主要通過直接的JDBC驅動和JDBC-ODBC橋驅動實現與數據庫的連接。

  一般來說,Java應用程序訪問數據庫的過程(如圖1所示)是:

  ①裝載數據庫驅動程序;

  ②通過JDBC建立數據庫連接;

  ③訪問數據庫,執行SQL語句;

  ④斷開數據庫連接。


圖1 Java數據庫訪問機制
  JDBC作為一種數據庫訪問技術,具有簡單易用的優點。但使用這種模式進行Web應用
  程序開發,存在很多問題:首先,每一次Web請求都要建立一次數據庫連接。建立連接是一個費時的活動,每次都得花費0.05s~1s的時間,而且系統還要分配內存資源。這個時間對於一次或幾次數據庫操作,或許感覺不出系統有多大的開銷。可是對於現在的Web應用,尤其是大型電子商務 網站,同時有幾百人甚至幾千人在線是很正常的事。在這種情況下,頻繁的進行數據庫連接操作勢必占用很多的系統資源,網站的響應速度必定下降,嚴重的甚至會造成服務器的崩潰。不是危言聳聽,這就是制約某些電子商務網站發展的技術瓶頸問題。其次,對於每一次數據庫連接,使用完后都得斷開。否則,如果程序出現異常而未能關閉,將會導致數據庫系統中的內存泄漏,最終將不得不重啟數據庫。還有,這種開發不能控制被創建的連接對象數,系統資源會被毫無顧及的分配出去,如連接過多,也可能導致內存泄漏,服務器崩潰。
 
  數據庫連接池(connection pool)的工作原理

  1、基本概念及原理
由上面的分析可以看出,問題的根源就在於對數據庫連接資源的低效管理。我們知道,

  對於共享資源,有一個很著名的 設計模式:資源池(Resource Pool)。該模式正是為了解決資源的頻繁分配﹑釋放所造成的問題。為解決上述問題,可以采用數據庫連接池技術。數據庫連接池的基本思想就是為數據庫連接建立一個“緩沖池”。預先在緩沖池中放入一定數量的連接,當需要建立數據庫連接時,只需從“緩沖池”中取出一個,使用完畢之后再放回去。我們可以通過設定連接池最大連接數來防止系統無盡的與數據庫連接。更為重要的是我們可以通過連接池的管理機制監視數據庫的連接的數量﹑使用情況,為系統開發﹑測試及性能調整提供依據。連接池的基本工作原理見下圖2。

圖2 連接池的基本工作原理
  2、服務器自帶的連接池
  JDBC的API中沒有提供連接池的方法。一些大型的WEB應用服務器如BEA的WebLogic和IBM的WebSphere等提供了連接池的機制,但是必須有其第三方的專用類方法支持連接池的用法。
  連接池關鍵問題分析
  1、並發問題
  為了使連接管理服務具有最大的通用性,必須考慮多線程環境,即並發問題。這個問題相對比較好解決,因為 Java語言自身提供了對並發管理的支持,使用synchronized關鍵字即可確保線程是同步的。使用方法為直接在類方法前面加上synchronized關鍵字,如:
public synchronized Connection getConnection()
  2、多數據庫服務器和多用戶
  對於大型的企業級應用,常常需要同時連接不同的數據庫(如連接 OracleSybase)。如何連接不同的數據庫呢?我們采用的策略是:設計一個符合單例模式的連接池管理類,在連接池管理類的唯一實例被創建時讀取一個資源文件,其中資源文件中存放着多個數據庫的url地址(<poolName.url>)﹑用戶名(<poolName.user>)﹑密碼(<poolName.password>)等信息。如tx.url=192.168.1.123:5000/tx_it,tx.user=cyl,tx.password=123456。根據資源文件提供的信息,創建多個連接池類的實例,每一個實例都是一個特定數據庫的連接池。連接池管理類實例為每個連接池實例取一個名字,通過不同的名字來管理不同的連接池。
  對於同一個數據庫有多個用戶使用不同的名稱和密碼訪問的情況,也可以通過資源文件處理,即在資源文件中設置多個具有相同url地址,但具有不同用戶名和密碼的數據庫連接信息。
  3、事務處理

  我們知道,事務具有原子性,此時要求對數據庫的操作符合“ALL-ALL-NOTHING”原則,即對於一組SQL語句要么全做,要么全不做。
Java語言中,Connection類本身提供了對事務的支持,可以通過設置Connection的AutoCommit屬性為false,然后顯式的調用commit或rollback方法來實現。但要高效的進行Connection復用,就必須提供相應的事務支持機制。可采用每一個事務獨占一個連接來實現,這種方法可以大大降低事務管理的復雜性。

  4、連接池的分配與釋放
  連接池的分配與釋放,對系統的性能有很大的影響。合理的分配與釋放,可以提高連接的復用度,從而降低建立新連接的開銷,同時還可以加快用戶的訪問速度。
  對於連接的管理可使用空閑池。即把已經創建但尚未分配出去的連接按創建時間存放到一個空閑池中。每當用戶請求一個連接時,系統首先檢查空閑池內有沒有空閑連接。如果有就把建立時間最長(通過容器的順序存放實現)的那個連接分配給他(實際是先做連接是否有效的判斷,如果可用就分配給用戶,如不可用就把這個連接從空閑池刪掉,重新檢測空閑池是否還有連接);如果沒有則檢查當前所開連接池是否達到連接池所允許的最大連接數(maxConn),如果沒有達到,就新建一個連接,如果已經達到,就等待一定的時間(timeout)。如果在等待的時間內有連接被釋放出來就可以把這個連接分配給等待的用戶,如果等待時間超過預定時間timeout,則返回空值(null)。系統對已經分配出去正在使用的連接只做計數,當使用完后再返還給空閑池。對於空閑連接的狀態,可開辟專門的線程定時檢測,這樣會花費一定的系統開銷,但可以保證較快的響應速度。也可采取不開辟專門線程,只是在分配前檢測的方法。
  5、連接池的配置與維護
  連接池中到底應該放置多少連接,才能使系統的性能最佳?系統可采取設置最小連接數(minConn)和最大連接數(maxConn)來控制連接池中的連接。最小連接數是系統啟動時連接池所創建的連接數。如果創建過多,則系統啟動就慢,但創建后系統的響應速度會很快;如果創建過少,則系統啟動的很快,響應起來卻慢。這樣,可以在開發時,設置較小的最小連接數,開發起來會快,而在系統實際使用時設置較大的,因為這樣對訪問客戶來說速度會快些。最大連接數是連接池中允許連接的最大數目,具體設置多少,要看系統的訪問量,可通過反復測試,找到最佳點。

  如何確保連接池中的最小連接數呢?有動態和靜態兩種策略。動態即每隔一定時間就對連接池進行檢測,如果發現連接數量小於最小連接數,則補充相應數量的新連接,以保證連接池的正常運轉。靜態是發現空閑連接不夠時再去檢查。
連接池的實現

  1、連接池模型
  本文討論的連接池包括一個連接池類(DBConnectionPool)和一個連接池管理類(DBConnetionPoolManager)和一個配置文件操作類(ParseDSConfig)。連接池類是對某一 數據庫所有連接的“緩沖池”,主要實現以下功能:①從連接池獲取或創建可用連接;②使用完畢之后,把連接返還給連接池;③在系統關閉前,斷開所有連接並釋放連接占用的系統資源;④還能夠處理無效連接(原來登記為可用的連接,由於某種原因不再可用,如超時,通訊問題),並能夠限制連接池中的連接總數不低於某個預定值和不超過某個預定值。(5)當多數據庫時,且數據庫是動態增加的話,將會加到配置文件中。
  連接池管理類是連接池類的外覆類(wrapper),符合單例模式,即系統中只能有一個連接池管理類的實例。其主要用於對多個連接池對象的管理,具有以下功能:①裝載並注冊特定數據庫的JDBC驅動程序;②根據屬性文件給定的信息,創建連接池對象;③為方便管理多個連接池對象,為每一個連接池對象取一個名字,實現連接池名字與其實例之間的映射;④跟蹤客戶使用連接情況,以便需要是關閉連接釋放資源。連接池管理類的引入主要是為了方便對多個連接池的使用和管理,如系統需要連接不同的數據庫,或連接相同的數據庫但由於 安全性問題,需要不同的用戶使用不同的名稱和密碼。
         2、連接池實現(經過本人改版,可以適用多數據庫類型的應用以及一種數據庫類型多個數據庫且數據  庫的數量可以動態增加的應用程序)
         1),DBConnectionPool.java   數據庫連接池類
         2),DBConnectionManager .java   數據庫管理類
         3),DSConfigBean .java                單個數據庫連接信息Bean
         4),ParseDSConfig.java                操作多(這個'多'包括不同的數據庫和同一種數據庫有多個數據庫)
                                                            數據 配置文件xml
         5),ds.config.xml                           數據庫配置文件xml
         原代碼如下: 
        DBConnectionPool.java  
        ----------------------------------------------------------
      /**
 * 數據庫連接池類
 */
package com.chunkyo.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
/**
 * @author chenyanlin
 *
 */
public class DBConnectionPool implements TimerListener {
 private Connection con=null;
 private int inUsed=0;    //使用的連接數
 private ArrayList freeConnections = new ArrayList();//容器,空閑連接
 private int minConn;     //最小連接數
 private int maxConn;     //最大連接
 private String name;     //連接池名字
 private String password; //密碼
 private String url;      //數據庫連接地址
 private String driver;   //驅動
 private String user;     //用戶名
 public Timer timer;      //定時
 /**
  *
  */
 public DBConnectionPool() {
  // TODO Auto-generated constructor stub
 }
 /**
  * 創建連接池
  * @param driver
  * @param name
  * @param URL
  * @param user
  * @param password
  * @param maxConn
  */
 public DBConnectionPool(String name, String driver,String URL, String user, String password, int maxConn)
 {
  this.name=name;
  this.driver=driver;
  this.url=URL;
  this.user=user;
  this.password=password;
  this.maxConn=maxConn;
 }
 /**
  * 用完,釋放連接
  * @param con
  */
 public synchronized void freeConnection(Connection con)
 {
  this.freeConnections.add(con);//添加到空閑連接的末尾
  this.inUsed--;
 }
 /**
  * timeout  根據timeout得到連接
  * @param timeout
  * @return
  */
 public synchronized Connection getConnection(long timeout)
 {
  Connection con=null;
  if(this.freeConnections.size()>0)
  {
   con=(Connection)this.freeConnections.get(0);
   if(con==null)con=getConnection(timeout); //繼續獲得連接
  }
  else
  {
   con=newConnection(); //新建連接
  }
  if(this.maxConn==0||this.maxConn<this.inUsed)
  {
   con=null;//達到最大連接數,暫時不能獲得連接了。
  }
  if(con!=null)
  {
   this.inUsed++;
  }
  return con;
 }
 /**
  *
  * 從連接池里得到連接
  * @return
  */
 public synchronized Connection getConnection()
 {
  Connection con=null;
  if(this.freeConnections.size()>0)
  {
   con=(Connection)this.freeConnections.get(0);
   this.freeConnections.remove(0);//如果連接分配出去了,就從空閑連接里刪除
   if(con==null)con=getConnection(); //繼續獲得連接
  }
  else
  {
   con=newConnection(); //新建連接
  }
  if(this.maxConn==0||this.maxConn<this.inUsed)
  {
   con=null;//等待 超過最大連接時
  }
  if(con!=null)
  {
   this.inUsed++;
   System.out.println("得到 "+this.name+" 的連接,現有"+inUsed+"個連接在使用!");
  }
  return con;
 }
 /**
  *釋放全部連接
  *
  */
 public synchronized void release()
 {
  Iterator allConns=this.freeConnections.iterator();
  while(allConns.hasNext())
  {
   Connection con=(Connection)allConns.next();
   try
   {
    con.close();
   }
   catch(SQLException e)
   {
    e.printStackTrace();
   }
   
  }
  this.freeConnections.clear();
   
 }
 /**
  * 創建新連接
  * @return
  */
 private Connection newConnection()
 {
  try {
   Class.forName(driver);
   con=DriverManager.getConnection(url, user, password);
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("sorry can't find db driver!");
  } catch (SQLException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
   System.out.println("sorry can't create Connection!");
  }
  return con;
  
 }
 /**
  * 定時處理函數
  */
 public synchronized void TimerEvent()
 {
     //暫時還沒有實現以后會加上的
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
 /**
  * @return the driver
  */
 public String getDriver() {
  return driver;
 }
 /**
  * @param driver the driver to set
  */
 public void setDriver(String driver) {
  this.driver = driver;
 }
 /**
  * @return the maxConn
  */
 public int getMaxConn() {
  return maxConn;
 }
 /**
  * @param maxConn the maxConn to set
  */
 public void setMaxConn(int maxConn) {
  this.maxConn = maxConn;
 }
 /**
  * @return the minConn
  */
 public int getMinConn() {
  return minConn;
 }
 /**
  * @param minConn the minConn to set
  */
 public void setMinConn(int minConn) {
  this.minConn = minConn;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the password
  */
 public String getPassword() {
  return password;
 }
 /**
  * @param password the password to set
  */
 public void setPassword(String password) {
  this.password = password;
 }
 /**
  * @return the url
  */
 public String getUrl() {
  return url;
 }
 /**
  * @param url the url to set
  */
 public void setUrl(String url) {
  this.url = url;
 }
 /**
  * @return the user
  */
 public String getUser() {
  return user;
 }
 /**
  * @param user the user to set
  */
 public void setUser(String user) {
  this.user = user;
 }
}

-------------------------------------------
 DBConnectionManager .java
------------------------------------------
/**
 * 數據庫連接池管理類
 */
package com.chunkyo.db;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
/**
 * @author chenyanlin
 *
 */
public class DBConnectionManager {
 static private DBConnectionManager instance;//唯一數據庫連接池管理實例類
 static private int clients;                 //客戶連接數
 private Vector drivers  = new Vector();//驅動信息
 private Hashtable pools=new Hashtable();//連接池
 
 /**
  * 實例化管理類
  */
 public DBConnectionManager() {
  // TODO Auto-generated constructor stub
  this.init();
 }
 /**
  * 得到唯一實例管理類
  * @return
  */
 static synchronized public DBConnectionManager getInstance()
 {
  if(instance==null)
  {
   instance=new DBConnectionManager();
  }
  return instance;
  
 }
 /**
  * 釋放連接
  * @param name
  * @param con
  */
 public void freeConnection(String name, Connection con)
 {
  DBConnectionPool pool=(DBConnectionPool)pools.get(name);//根據關鍵名字得到連接池
  if(pool!=null)
  pool.freeConnection(con);//釋放連接
 }
 /**
  * 得到一個連接根據連接池的名字name
  * @param name
  * @return
  */
 public Connection getConnection(String name)
 {
  DBConnectionPool pool=null;
  Connection con=null;
  pool=(DBConnectionPool)pools.get(name);//從名字中獲取連接池
  con=pool.getConnection();//從選定的連接池中獲得連接
  if(con!=null)
  System.out.println("得到連接。。。");
  return con;
 }
 /**
  * 得到一個連接,根據連接池的名字和等待時間
  * @param name
  * @param time
  * @return
  */
 public Connection getConnection(String name, long timeout)
 {
  DBConnectionPool pool=null;
  Connection con=null;
  pool=(DBConnectionPool)pools.get(name);//從名字中獲取連接池
  con=pool.getConnection(timeout);//從選定的連接池中獲得連接
  System.out.println("得到連接。。。");
  return con;
 }
 /**
  * 釋放所有連接
  */
 public synchronized void release()
 {
  Enumeration allpools=pools.elements();
  while(allpools.hasMoreElements())
  {
   DBConnectionPool pool=(DBConnectionPool)allpools.nextElement();
   if(pool!=null)pool.release();
  }
  pools.clear();
 }
 /**
  * 創建連接池
  * @param props
  */
 private void createPools(DSConfigBean dsb)
 {
  DBConnectionPool dbpool=new DBConnectionPool();
  dbpool.setName(dsb.getName());
  dbpool.setDriver(dsb.getDriver());
  dbpool.setUrl(dsb.getUrl());
  dbpool.setUser(dsb.getUsername());
  dbpool.setPassword(dsb.getPassword());
  dbpool.setMaxConn(dsb.getMaxconn());
  System.out.println("ioio:"+dsb.getMaxconn());
  pools.put(dsb.getName(), dbpool);
 }
 /**
  * 初始化連接池的參數
  */
 private void init()
 {
  //加載驅動程序
  this.loadDrivers();
  //創建連接池
  Iterator alldriver=drivers.iterator();
  while(alldriver.hasNext())
  {
   this.createPools((DSConfigBean)alldriver.next());
   System.out.println("創建連接池。。。");
   
  }
  System.out.println("創建連接池完畢。。。");
 }
 /**
  * 加載驅動程序
  * @param props
  */
 private void loadDrivers()
 {
  ParseDSConfig pd=new ParseDSConfig();
 //讀取數據庫配置文件
  drivers=pd.readConfigInfo("ds.config.xml");
  System.out.println("加載驅動程序。。。");
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
}
----------------------------------------
DSConfigBean.java
----------------------------------------
/**
 * 配置文件Bean類
 */
package com.chunkyo.db;
/**
 * @author chenyanlin
 *
 */
public class DSConfigBean {
 private String type     =""; //數據庫類型
 private String name     =""; //連接池名字
 private String driver   =""; //數據庫驅動
 private String url      =""; //數據庫url
 private String username =""; //用戶名
 private String password =""; //密碼
 private int maxconn  =0; //最大連接數
 /**
  *
  */
 public DSConfigBean() {
  // TODO Auto-generated constructor stub
 }
 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
 }
 /**
  * @return the driver
  */
 public String getDriver() {
  return driver;
 }
 /**
  * @param driver the driver to set
  */
 public void setDriver(String driver) {
  this.driver = driver;
 }
 /**
  * @return the maxconn
  */
 public int getMaxconn() {
  return maxconn;
 }
 /**
  * @param maxconn the maxconn to set
  */
 public void setMaxconn(int maxconn) {
  this.maxconn = maxconn;
 }
 /**
  * @return the name
  */
 public String getName() {
  return name;
 }
 /**
  * @param name the name to set
  */
 public void setName(String name) {
  this.name = name;
 }
 /**
  * @return the password
  */
 public String getPassword() {
  return password;
 }
 /**
  * @param password the password to set
  */
 public void setPassword(String password) {
  this.password = password;
 }
 /**
  * @return the type
  */
 public String getType() {
  return type;
 }
 /**
  * @param type the type to set
  */
 public void setType(String type) {
  this.type = type;
 }
 /**
  * @return the url
  */
 public String getUrl() {
  return url;
 }
 /**
  * @param url the url to set
  */
 public void setUrl(String url) {
  this.url = url;
 }
 /**
  * @return the username
  */
 public String getUsername() {
  return username;
 }
 /**
  * @param username the username to set
  */
 public void setUsername(String username) {
  this.username = username;
 }
}
-----------------------------------------------------
ParseDSConfig.java
-----------------------------------------------------
/**
 * 操作配置文件類 讀  寫 修改 刪除等操作
 */
package com.chunkyo.db;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/**
 * @author chenyanlin
 *
 */
public class ParseDSConfig {
 /**
  * 構造函數
  */
 public ParseDSConfig() {
  // TODO Auto-generated constructor stub
 }
 /**
  * 讀取xml配置文件
  * @param path
  * @return
  */
 public Vector readConfigInfo(String path)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  Vector dsConfig=null;
  FileInputStream fi = null;
  try
  {
   fi=new FileInputStream(rpath);//讀取路徑文件
   dsConfig=new Vector();
   SAXBuilder sb=new SAXBuilder();
   Document doc=sb.build(fi);
   Element root=doc.getRootElement();
   List pools=root.getChildren();
   Element pool=null;
   Iterator allPool=pools.iterator();
   while(allPool.hasNext())
   {
    pool=(Element)allPool.next();
    DSConfigBean dscBean=new DSConfigBean();
    dscBean.setType(pool.getChild("type").getText());
    dscBean.setName(pool.getChild("name").getText());
    System.out.println(dscBean.getName());
    dscBean.setDriver(pool.getChild("driver").getText());
    dscBean.setUrl(pool.getChild("url").getText());
    dscBean.setUsername(pool.getChild("username").getText());
    dscBean.setPassword(pool.getChild("password").getText());
    dscBean.setMaxconn(Integer.parseInt(pool.getChild("maxconn").getText()));
    dsConfig.add(dscBean);
   }
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  finally
  {
   try {
    fi.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  return dsConfig;
 }
/**
 *修改配置文件 沒時間寫 過段時間再貼上去 其實一樣的
 */
 public void modifyConfigInfo(String path,DSConfigBean dsb) throws Exception
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi=null; //讀出
  FileOutputStream fo=null; //寫入
  
 }
/**
 *增加配置文件
 *
 */
 public void addConfigInfo(String path,DSConfigBean dsb)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi=null;
  FileOutputStream fo=null;
  try
  {
   fi=new FileInputStream(rpath);//讀取xml流
   
   SAXBuilder sb=new SAXBuilder();
   
   Document doc=sb.build(fi); //得到xml
   Element root=doc.getRootElement();
   List pools=root.getChildren();//得到xml子樹
   
   Element newpool=new Element("pool"); //創建新連接池
   
   Element pooltype=new Element("type"); //設置連接池類型
   pooltype.setText(dsb.getType());
   newpool.addContent(pooltype);
   
   Element poolname=new Element("name");//設置連接池名字
   poolname.setText(dsb.getName());
   newpool.addContent(poolname);
   
   Element pooldriver=new Element("driver"); //設置連接池驅動
   pooldriver.addContent(dsb.getDriver());
   newpool.addContent(pooldriver);
   
   Element poolurl=new Element("url");//設置連接池url
   poolurl.setText(dsb.getUrl());
   newpool.addContent(poolurl);
   
   Element poolusername=new Element("username");//設置連接池用戶名
   poolusername.setText(dsb.getUsername());
   newpool.addContent(poolusername);
   
   Element poolpassword=new Element("password");//設置連接池密碼
   poolpassword.setText(dsb.getPassword());
   newpool.addContent(poolpassword);
   
   Element poolmaxconn=new Element("maxconn");//設置連接池最大連接
   poolmaxconn.setText(String.valueOf(dsb.getMaxconn()));
   newpool.addContent(poolmaxconn);
   pools.add(newpool);//將child添加到root
   Format format = Format.getPrettyFormat();
      format.setIndent("");
      format.setEncoding("utf-8");
      XMLOutputter outp = new XMLOutputter(format);
      fo = new FileOutputStream(rpath);
      outp.output(doc, fo);
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  finally
  {
   
  }
 }
 /**
  *刪除配置文件
  */
 public void delConfigInfo(String path,String name)
 {
  String rpath=this.getClass().getResource("").getPath().substring(1)+path;
  FileInputStream fi = null;
  FileOutputStream fo=null;
  try
  {
   fi=new FileInputStream(rpath);//讀取路徑文件
   SAXBuilder sb=new SAXBuilder();
   Document doc=sb.build(fi);
   Element root=doc.getRootElement();
   List pools=root.getChildren();
   Element pool=null;
   Iterator allPool=pools.iterator();
   while(allPool.hasNext())
   {
    pool=(Element)allPool.next();
    if(pool.getChild("name").getText().equals(name))
    {
     pools.remove(pool);
     break;
    }
   }
   Format format = Format.getPrettyFormat();
      format.setIndent("");
      format.setEncoding("utf-8");
      XMLOutputter outp = new XMLOutputter(format);
      fo = new FileOutputStream(rpath);
      outp.output(doc, fo);
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (JDOMException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  finally
  {
   try {
    fi.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }
 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  ParseDSConfig pd=new ParseDSConfig();
  String path="ds.config.xml";
  pd.readConfigInfo(path);
  //pd.delConfigInfo(path, "tj012006");
  DSConfigBean dsb=new DSConfigBean();
  dsb.setType("oracle");
  dsb.setName("yyy004");
  dsb.setDriver("org.oracle.jdbc");
  dsb.setUrl("jdbc:oracle://localhost");
  dsb.setUsername("sa");
  dsb.setPassword("");
  dsb.setMaxconn(1000);
  pd.addConfigInfo(path, dsb);
  pd.delConfigInfo(path, "yyy001");
 }

}

--------------------------------------
ds.config.xml   配置文件
--------------------------------------


<ds-config>
<pool>
<type>mysql</type>
<name>user</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user</url>
<username>sa</username>
<password>123456</password>
<maxconn>100</maxconn>
</pool>
<pool>
<type>mysql</type>
<name>user2</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user2</url>
<username>sa</username>
<password>1234</password>
<maxconn>10</maxconn>
</pool>
<pool>
<type>sql2000</type>
<name>books</name>
<driver>com.microsoft.sqlserver.driver</driver>
<url>jdbc:sqlserver://localhost:1433/books:databasename=books</url>
<username>sa</username>
<password></password>
<maxconn>100</maxconn>
</pool>
</ds-config>


3. 連接池的使用
  1。Connection的獲得和釋放
  DBConnectionManager   connectionMan=DBConnectionManager .getInstance();//得到唯一實例
   //得到連接
   String name="mysql";//從上下文得到你要訪問的數據庫的名字
   Connection  con=connectionMan.getConnection(name);
  //使用
  。。。。。。。
  // 使用完畢
 connectionMan.freeConnection(name,con);//釋放,但並未斷開連接
 2。數據庫連接的動態增加和連接池的動態增加
      1。調用xml操作增加類

      2。重新實例華連接池管理池類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM