DBCP、c3p0、Druid三大連接池區別


 

DBCP、c3p0、Druid三大連接池區別

一、連接池優勢

如果一個項目中如果需要多個連接,如果一直獲取連接,斷開連接,這樣比較浪費資源;

如果創建一個池,用池來管理Connection,這樣就可以重復使用Connection。

有了池我們就不用自己來創建Connection,而是通過池來獲取Connection對象。當使用完Connection后,調用Connection的close()方法也不會真的關閉Connection,而是把Connection“歸還”給池。

池就可以再利用這個Connection對象了。這里我們常用的連接池有三種,分別是:DBCP連接池、C3P0連接池和DRUID連接池;

二、DBCP連接池

DBCP是一個依賴Jakarta commons-pool對象池機制的數據庫連接池.DBCP可以直接的在應用程序中使用,Tomcat的數據源使用的就是DBCP;

使用連接池的第一項工作就是導包,這里需要的兩個jar包分別是:

在使用寫連接池工具類的時候,可以通過配置文件來連接數據庫,配置文件中記錄了連接數據庫的驅動、URL、用戶名和密碼等信息;但要注意這里的文件后綴為:“.properties”。

把通過配置文件連接數據庫的部分寫在靜態代碼塊中,隨着類的加載只加載一次。出了連接數據庫,還要提供一個獲得數據源的方法和一個獲取連接的方法;

下邊是把連接池寫成一個工具類的代碼,寫成工具類和直接使用的代碼幾乎相同,就不在重復的寫了。

配置文件的部分內容:

代碼:(配置文件的命名為:dbcp.properties

public class DBCPUtils {
    //首先定義私有的datasource
    private static DataSource datasource;
    //把配置文件部分放在靜態代碼塊中,調用時直接加載
    static{
        try {
            //加載文件
            InputStream is=DBCPUtils.class.getClassLoader().getResourceAsStream("dbcp.properties");
            //實例化properties集合
            Properties prop=new Properties();    
            prop.load(is);        
            //首先加載核心類     
            datasource=BasicDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //提供獲得數據源  
    public static DataSource getDataSource(){
        return datasource;
    }
    //提供獲得連接     
    public static Connection getConnection() throws SQLException{
        return datasource.getConnection();
    }
}

在寫成工具類后都要對外提供一個數據源DateSource和一個連接Connection。作用是,如果我們在進行數據庫操作的時候要是使用DBUtils類的時候,就要使用QueryRunner核心類,而這個類在進行與數據庫連接的時候只要一句代碼:QueryRunner qr=newQueryRunner(數據源);

通過連接池獲得:DBCPUtils.getDataSource()獲得。如果不使用DBUtils工具類,我們就可以直接通過DBCPUtils .getConnection()來直接獲得連接。

三、C3P0連接池

c3p0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發布,包括了實現jdbc3和jdbc2擴展規范說明的Connection 和Statement 池的DataSources 對象。

使用連接池的第一項工作就是導包,這里需要的兩個jar包分別是:

這種連接池在進行數據庫的連接的時候有兩種連接方法:使用配置文件和不使用配置文件兩種。

當然使用配置文件的時候代碼要簡介的多,配置文件中同樣是記錄了連接數據庫的驅動、URL、用戶名和密碼等信息。

(1)不使用配置文件的代碼:三個步驟:

<1>、導入核心類:ComboPooledDataSource 

<2>、基本的四項設置,也就是設置驅動,URL,用戶名和密碼等四項。

<3>、其他四項。代碼如下:

public class c3p0_test01 {
    public static void main(String[] args) throws Exception {
        //導入一個核心類
        ComboPooledDataSource  dataSource = new ComboPooledDataSource();
        //基本四項設置
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/eeday09");
        dataSource.setUser("root");
        dataSource.setPassword("123");
        //其他四項設置
        dataSource.setInitialPoolSize(10);  //初始化連接個數
        dataSource.setMaxPoolSize(40);   //最大鏈接數
        dataSource.setMinPoolSize(5);  //設置最小鏈接數
        dataSource.setAcquireIncrement(2);    //設置每次增加的連接數
        Connection conn=dataSource.getConnection();      //進行數據庫連接
        System.out.println(conn);
    }
}

(2)如果使用配置文件連接數據庫,其中配置文件中的內容為:

使用配置文件進行連接的寫法如下:

import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import com.mchange.v2.c3p0.ComboPooledDataSource;
 
public class C3P0Utils {
    //1、提供私有化的數據源    使用默認設置
    private static ComboPooledDataSource datasource=new ComboPooledDataSource();
    //使用命名配置
    //private static ComboPooledDataSource datasource =new ComboPooledDataSource("itheima");
    //2.提供對外的數據源
     public static DataSource getDataSource(){
        return datasource;    
    }
    //3.提供對外的鏈接  
    public static Connection getConnection() throws SQLException{
        return datasource.getConnection();
    }
}

在寫成工具類后都要對外提供一個數據源DateSource和一個連接Connection。作用是,如果我們在進行數據庫操作的時候要是使用DBUtils類的時候,就要使用QueryRunner核心類,而這個類在進行與數據庫連接的時候只要一句代碼:QueryRunner qr=newQueryRunner(數據源);

我們可以通過連接池獲得:C3P0Utils.getDataSource() 獲得。如果不使用DBUtils工具類,我們就可以直接通過C3P0Utils.getConnection()來直接獲得連接。

四、Druid連接池 

Druid首先是一個數據庫連接池。Druid是目前最好的數據庫連接池,在功能、性能、擴展性方面,都超過其他數據庫連接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已經在阿里巴巴部署了超過600個應用,經過一年多生產環境大規模部署的嚴苛考驗。

它不僅僅是一個數據庫連接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個 SQL Parser。支持所有JDBC兼容的數據庫,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等等。Druid針對Oracle和MySql做了特別優化,比如Oracle的PS Cache內存占用優化,MySql的ping檢測優化。Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,這是一個手寫的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象語法樹很方便。簡單SQL語句用時10微秒以內,復雜SQL用時30微秒。通過Druid提供的SQL Parser可以在JDBC層攔截SQL做相應處理,比如說分庫分表、審計等。Druid防御SQL注入攻擊的WallFilter就是通過Druid的SQL Parser分析語義實現的。

使用步驟:

1,使用連接池的第一項工作就是導包,這里需要的jar包分別是:druid-1.1.4.jar   1.1.4

2,druid.properties 文件內容:

# 配置數據庫的連接參數
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=root
​
# 配置連接池的參數
initialSize=5
maxActive=10
maxWait=3000
maxIdle=6
minIdle=3

3,連接池工具類:

/**
1)創建私有靜態數據源成員變量DataSource ds
2)在靜態代碼塊中創建連接池
a)創建屬性對象
b)從類路徑下加載屬性文件,得到輸入流對象
c)通過工廠類創建一個數據源
3)創建公有的得到數據源的方法getDataSource()
4)創建得到連接對象的方法 getConnection()
5)創建釋放資源的方法 close()
*/

/**
 * 連接池的工具類
 */
public class DataSourceUtils {
    //創建一個成員變量
    private static DataSource ds;
    /**
     * 加載的代碼寫在靜態代碼塊中
     */
    static {
        try {
            Properties info = new Properties();
            //加載類路徑下,即src目錄下的druid.properties這個文件
            info.load(DataSourceUtils.class.getResourceAsStream("/druid.properties"));
            
            //讀取屬性文件創建連接池
            ds = DruidDataSourceFactory.createDataSource(info);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 得到數據源
     */
    public static DataSource getDataSource() {
        return ds;
    }
    /**
     * 得到連接對象
     */
    public static Connection getConnection() {
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 釋放資源
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(Connection conn, Statement stmt) {
        close(conn, stmt, null);
    }
}

4,數據源工具類的使用:

public class DemoAdd {
    public static void main(String[] args) {
        //1. 創建連接對象,通過連接池工具類
        Connection conn = null;
        PreparedStatement ps = null;
        int row = 0;
        try {
            conn = DataSourceUtils.getConnection();
            //2. 創建語句對象
           ps = conn.prepareStatement("INSERT INTO student values(null,?,?,?)");
           ps.setString(1,"張遼");
           ps.setInt(2,1);
           ps.setString(3,"194-06-16");
           //3. 使用executeUpdate()寫入到數據庫
            row = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //4. 釋放資源
            DataSourceUtils.close(conn, ps);
        }
        System.out.println("添加了" + row);
    }
}

五、三者區別

我們從連接池配置的基本配置、關鍵配置、性能配置等主要配置來分析:

1,基本配置

基本配置是指連接池進行數據庫連接的四個基本必需配置:
傳遞給JDBC驅動的用於連接數據庫的用戶名、密碼、URL以及驅動類名。

 注:在Druid連接池的配置中,driverClassName可配可不配,如果不配置會根據url自動識別dbType(數據庫類型),然后選擇相應的driverClassName。

2,關鍵配置

為了發揮數據庫連接池的作用,在初始化時將創建一定數量的數據庫連接放到連接池中,這些數據庫連接的數量是由最小數據庫連接數來設定的。無論這些數 據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池 請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中。
最小連接數:是數據庫一直保持的數據庫連接數,所以如果應用程序對數據庫連接的使用量不大,將有大量的數據庫資源被浪費。
初始化連接數:連接池啟動時創建的初始化數據庫連接數量。
最大連接數:是連接池能申請的最大連接數,如果數據庫連接請求超過此數,后面的數據庫連接請求被加入到等待隊列中。
最大等待時間:當沒有可用連接時,連接池等待連接被歸還的最大時間,超過時間則拋出異常,可設置參數為0或者負數使得無限等待(根據不同連接池配置)。

 

注1:在DBCP連接池的配置中,還有一個maxIdle的屬性,表示最大空閑連接數,超過的空閑連接將被釋放,默認值為8。對應的該屬性在Druid連接池已不再使用,配置了也沒有效果,c3p0連接池則沒有對應的屬性。

注2:數據庫連接池在初始化的時候會創建initialSize個連接,當有數據庫操作時,會從池中取出一個連接。如果當前池中正在使用的連接數等 於maxActive,則會等待一段時間,等待其他操作釋放掉某一個連接,如果這個等待時間超過了maxWait,則會報錯;如果當前正在使用的連接數沒 有達到maxActive,則判斷當前是否空閑連接,如果有則直接使用空閑連接,如果沒有則新建立一個連接。在連接使用完畢后,不是將其物理連接關閉,而 是將其放入池中等待其他操作復用。

 3,性能配置

 (1)預緩存設置:

  即是PSCache,PSCache對支持游標的數據庫性能提升巨大,比如說oracle。JDBC的標准參數,用以控制數據源內加載的 PreparedStatements數量。但由於預緩存的statements屬於單個connection而不是整個連接池,所以設置這個參數需要考 慮到多方面的因素。
  單個連接擁有的最大緩存數:要啟用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改為true。在Druid中,不會存在Oracle下PSCache占用內存過多的問題,可以把這個數值配置大一些,比如說100

(2)連接有效性檢測設置:

  連接池內部有機制判斷,如果當前的總的連接數少於miniIdle,則會建立新的空閑連接,以保證連接數得到miniIdle。如果當前連接池中某 個連接在空閑了timeBetweenEvictionRunsMillis時間后任然沒有使用,則被物理性的關閉掉。有些數據庫連接的時候有超時限制 (mysql連接在8小時后斷開),或者由於網絡中斷等原因,連接池的連接會出現失效的情況,這時候設置一個testWhileIdle參數為true, 可以保證連接池內部定時檢測連接的可用性,不可用的連接會被拋棄或者重建,最大情況的保證從連接池中得到的Connection對象是可用的。當然,為了 保證絕對的可用性,你也可以使用testOnBorrow為true(即在獲取Connection對象時檢測其可用性),不過這樣會影響性能。

(3)超時連接關閉設置:

  removeAbandoned參數,用來檢測到當前使用的連接是否發生了連接泄露,所以在代碼內部就假定如果一個連接建立連接的時間很長,則將其認定為泄露,繼而強制將其關閉掉。

(4)c3p0重連設置:

  設置獲取連接失敗后,是否重新連接以及間隔時間。

六、DBCP、C3P0、DRUID三大連接池屬性說明表

1,DBCP 屬性說明表

2,C3P0  屬性說明表

(3)DRUID 屬性說明表

 

 

 


免責聲明!

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



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