Java數據庫連接池dbcp的用法

yg3n 9年前發布 | 48K 次閱讀 dbcp Java開發

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

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

一般來說,Java應用程序訪問數據庫的過程是:

①裝載數據庫驅動程序;

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

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

④斷開數據庫連接。

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

由上面的分析可以看出,問題的根源就在于對數據庫連接資源的低效管理。我們知道,

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

    import java.sql.Connection;  
    import java.sql.PreparedStatement;  
    import java.sql.ResultSet;  

    import org.apache.commons.dbcp.BasicDataSource;  
    import org.apache.log4j.Logger;  

    /** 
     * Description: 數據庫連接池類 
     * @filename DataSourceFactory.java  
     * @date 2013年8月21日 19:47:21 
     * @author Herman.Xiong 
     * @version 1.0 
     * Copyright (c) 2013 Company,Inc. All Rights Reserved. 
     */  
    public class DataSourceFactory {  
        private static Logger log = Logger.getLogger(DataSourceFactory.class);  
        private static BasicDataSource bs = null;  
        public static String driver,url,userName,password;  

        /** 
         * 創建數據源 
         * @return 
         */  
        public static BasicDataSource getDataSource() throws Exception{  
            if(bs==null){  
                log.info("數據庫連接信息:[driver:"+driver+",url:"+url+",userName:"+userName+",password:"+password+"]");  
                bs = new BasicDataSource();  
                bs.setDriverClassName(driver);  
                bs.setUrl(url);  
                bs.setUsername(userName);  
                bs.setPassword(password);  
                bs.setMaxActive(200);//設置最大并發數  
                bs.setInitialSize(30);//數據庫初始化時,創建的連接個數  
                bs.setMinIdle(50);//最小空閑連接數  
                bs.setMaxIdle(200);//數據庫最大連接數  
                bs.setMaxWait(1000);  
                bs.setMinEvictableIdleTimeMillis(60*1000);//空閑連接60秒中后釋放  
                bs.setTimeBetweenEvictionRunsMillis(5*60*1000);//5分鐘檢測一次是否有死掉的線程  
                bs.setTestOnBorrow(true);  
            }  
            return bs;  
        }  

        /** 
         * 釋放數據源 
         */  
        public static void shutDownDataSource() throws Exception{  
            if(bs!=null){  
                bs.close();  
            }  
        }  

        /** 
         * 獲取數據庫連接 
         * @return 
         */  
        public static Connection getConnection(){  
            Connection con=null;  
            try {  
                if(bs!=null){  
                    con=bs.getConnection();  
                }else{  
                    con=getDataSource().getConnection();  
                }  
            } catch (Exception e) {  
                log.error(e.getMessage(), e);  
            }  
            return con;  
        }  

        /** 
         * 關閉連接 
         */  
        public static void closeCon(ResultSet rs,PreparedStatement ps,Connection con){  
            if(rs!=null){  
                try {  
                    rs.close();  
                } catch (Exception e) {  
                    log.error("關閉結果集ResultSet異常!"+e.getMessage(), e);  
                }  
            }  
            if(ps!=null){  
                try {  
                    ps.close();  
                } catch (Exception e) {  
                    log.error("預編譯SQL語句對象PreparedStatement關閉異常!"+e.getMessage(), e);  
                }  
            }  
            if(con!=null){  
                try {  
                    con.close();  
                } catch (Exception e) {  
                    log.error("關閉連接對象Connection異常!"+e.getMessage(), e);  
                }  
            }  
        }  
    }  

 本文由用戶 yg3n 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!