日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

自己做數(shù)據(jù)庫連接池(c3p0)...

 夜郎 2007-08-03

自己做數(shù)據(jù)庫連接池c3p0 


如何快速使用c3p0 - JDBC3 Connection and Statement Pooling
一、下載
從SourceForge 網(wǎng)站下載最新的版本 
http:///projects/c3p0/

二、快速體驗
把這一個文件lib/c3p0-0.9.1-pre9.jar復制到你的  CLASSPATH即可。

import com.mchange.v2.c3p0.*; 
... 
ComboPooledDataSource cpds = new ComboPooledDataSource(); 
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" ); 
cpds.setUser("dbuser"); 
cpds.setPassword("dbpassword"); 
你還可以設置如下參數(shù)
cpds.setMaxStatements( 180 ); 
然后你就可以從cpds.getConnection()獲得連接了。

最后,執(zhí)行下面語句銷毀cpds.
DataSources.destroy( cpds ); 

三、建立自定義連接池工廠
為了適應有多個數(shù)據(jù)源的單一系統(tǒng),現(xiàn)在定義在這個系統(tǒng)中使用key字符串來識別每一個數(shù)據(jù)源,如
oa - 識別 OA 系統(tǒng)
epr - 識別 ERP 系統(tǒng)
hr - 識別 HR 系統(tǒng)
等等
詳細代碼與注釋如下:
///////////////////////////////////////////////////////////////
package com.paipaiestore.database.c3p0;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.DataSources;
/**
 * 數(shù)據(jù)連接池工廠 
 * @author samland
 * @version 1.0, 2006-11
 */
public class DBPoolFactory {

 private static DBPoolFactory dbpoolFactory = new DBPoolFactory();
 /**
  * 連接池列表
  */
 private static Map poollist = new HashMap();

 private DBPoolFactory(){
  
 }
 
 public static DBPoolFactory getInstance(){
  return dbpoolFactory;
 }
 /**
  * 向連接池列表添加一個新的池化(Pooled)數(shù)據(jù)源
  * @param key 
  * @param configFile 配置文件名。為了簡化參數(shù)輸入與便于外部維護,可以把配置好的文件傳入這里分析
  */
 public void add(String key, String configFile) {
  //read config from file, and build a dbpool
 }
 /**
  * 向連接池列表添加一個新的池化(Pooled)數(shù)據(jù)源
  * @param key
  * @param driver 數(shù)據(jù)連接驅(qū)動,如com.mysql.jdbc.Driver
  * @param url 連接串, 如jdbc:mysql://localhost/samland
  * @param username 數(shù)據(jù)庫連接用戶名,如samland
  * @param password 數(shù)據(jù)庫連接用戶密碼
  * @throws Exception
  */
 public void add(String key, String driver, String url, String username, String password) 
  throws Exception{
  if (key==null) throw new Exception("DBPool ‘key‘ CANNOT be null") ;
  
  Class.forName(driver);
  DataSource ds_unpooled = DataSources.unpooledDataSource(url, username, password); 
  DataSource ds_pooled = DataSources.pooledDataSource( ds_unpooled );
  if (poollist.containsKey(key)){
   poollist.remove(key); 
  }
  poollist.put(key, ds_pooled);
 }
 /**
  * 根據(jù)key字符串獲取連接池
  * @param key
  * @return DBPool 連接池
  * @throws Exception
  */
 public DBPool getDBPool(String key) throws Exception{
  if (key==null) throw new Exception("DBPool ‘key‘ CANNOT be null") ;
  DataSource ds = (DataSource)poollist.get(key);
  DBPool dbpool = new DBPool();
  dbpool.setDs_pooled(ds);
  return dbpool;
 }

}
///////////////////////////////////////////////////////////////

四、連接池的使用
通過DBPool來獲取數(shù)據(jù)庫連接 (jdbc connection)。
4.1 由DBPoolFactory工廠產(chǎn)生一個DBPool
4.2 同時,DBPoolFactory工廠根據(jù)傳入的參數(shù)key向這個DBPool注入數(shù)據(jù)源
4.3 從DBPool產(chǎn)生線程內(nèi)的Connection
///////////////////////////////////////////////////////////////
package com.paipaiestore.database.c3p0;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

public class DBPool {
 /**
  * 數(shù)據(jù)庫連接。同一個線程使用同一個連接。
  */
 protected static ThreadLocal connection = new ThreadLocal();
 /**
  * 數(shù)據(jù)源,需由DBPoolFactory工廠注入
  */
 private DataSource ds_pooled;

 /**
  * 不能獨立構造,必須從DBPoolFactory工廠產(chǎn)生
  */
 protected DBPool(){}
 
 /**
  * get 數(shù)據(jù)源
  * @return
  */
 public DataSource getDs_pooled() {
  return ds_pooled;
 }

 /**
  * 注入數(shù)據(jù)源
  * @param ds_pooled
  */
 public void setDs_pooled(DataSource ds_pooled) {
  this.ds_pooled = ds_pooled;
 }

 /**
  * 獲得數(shù)據(jù)庫連接
  * 同一個線程只返回相同的一個連接。
  * @return Connection
  * @throws SQLException
  */
 public Connection getConnection() throws SQLException{
  Connection con = (Connection)connection.get();
  if (con==null) {
   con = ds_pooled.getConnection();
   connection.set(con);
  }
  return con;
 }
}
///////////////////////////////////////////////////////////////

五、改進線程內(nèi)數(shù)據(jù)庫連接的使用
為了適應程序已經(jīng)使用開的jdbc事務管理,因此需要改進DBPool成為Transaction類,
而原來的DBPool則縮減為如下代碼:
///////////////////////////////////////////////////////////////
public class DBPool {
 private DataSource ds_pooled;
 protected DBPool(){}
 public DataSource getDs_pooled() {
  return ds_pooled;
 }
 public void setDs_pooled(DataSource ds_pooled) {
  this.ds_pooled = ds_pooled;
 }
}
///////////////////////////////////////////////////////////////
package com.paipaiestore.database.c3p0;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

public class Transaction {
 /**
  * 數(shù)據(jù)庫連接。同一個線程使用同一個連接。
  */
 protected static ThreadLocal connection = new ThreadLocal();
 protected static boolean isInUsed = false;
 /**
  * 開始一個事務
  * 如果當前線程的數(shù)據(jù)庫連接不存在,則會新獲得一個數(shù)據(jù)庫連接
  * @param key 
  * @throws Exception
  */
 public static void beginTransaction(String key) throws Exception{
  Connection conn = (Connection)connection.get();
  if (conn==null) {
   conn = createConnection(key);
            setConnection(conn);
  }
  conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
        conn.setAutoCommit(false);
        isInUsed = true;
 }
 /**
  * 提交一個事務
  * @throws SQLException
  */
 public static void commitTransaction() throws SQLException {
   Connection conn = (Connection)connection.get();
   conn.commit();
 }
 /**
  * 回滾一個事務
  * @throws SQLException
  */
 public static void rollbackTransaction() throws SQLException {
   Connection conn = (Connection)connection.get();
   conn.rollback();
 }
 public static boolean getIsInUsed() {
  return isInUsed;
 } 
 private static void closeConnection() {
  try {
   Connection conn = (Connection)connection.get();
   if (conn!=null) {
    connection.set(null);
    conn.close();
   }
  }catch(SQLException sqlexception) { 
   
  }
 } 
 private static void close(ResultSet rs){
  try
        {
            Statement st = rs.getStatement();
            Connection conn = st.getConnection();
            rs.close();
            st.close();
            conn.close();
        }
        catch(Exception exception) { }
 } 
 /**
  * 獲得數(shù)據(jù)庫連接
  * 同一個線程只返回相同的一個連接。
  * @return
  * @throws SQLException
  */
 public static Connection getConnection() throws SQLException {
        Connection conn = null;
        conn = (Connection)connection.get();
        if(conn == null)
            throw new NullPointerException();
        else
            return conn;
    } 
 
 private static void setConnection(Connection conn){
  connection.set(conn);
 } 
 /**
  * 獲得一個新的數(shù)據(jù)庫連接
  * @param key
  * @return Connection
  * @throws Exception
  */
 private static Connection createConnection(String key)
  throws Exception  {
  DBPoolFactory df = DBPoolFactory.getInstance();
  DataSource ds_pooled = df.getDBPool(key).getDs_pooled() ;
  Connection conn = ds_pooled.getConnection();
  df = null;
        return conn;
    }
}
///////////////////////////////////////////////////////////////
六、測試
///////////////////////////////////////////////////////////////
package samland;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.paipaiestore.database.c3p0.DBPoolFactory;
import com.paipaiestore.database.c3p0.Transaction;

public class TestTransaction {
 
 /**
  * @param args
  */
 public static void main(String[] args) {
  DBPoolFactory df = DBPoolFactory.getInstance();
  
  Connection con  = null;
  Statement  stmt = null;
  ResultSet  rs   = null;
  try {
   df.add("jxc","com.mysql.jdbc.Driver","jdbc:mysql://paipaiestore.com/samland","samland","*****");
   
   Transaction.beginTransaction("samland");
   con = Transaction.getConnection();
   stmt = con.createStatement();
   rs = stmt.executeQuery("SELECT * FROM users");
   while (rs.next())
   {
    System.out.print( rs.getString(1) );
    System.out.print( rs.getString(2) );
    System.out.println( rs.getString(3) );
   }
   Transaction.commitTransaction();
   df = null;
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}
///////////////////////////////////////////////////////////////  

未經(jīng)嚴格測試,請使用者提出修改意見。

下一步需要增加檢測當前連接池狀態(tài)的功能。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多