1. 程式人生 > >Mysql學習--07.c3p0資料庫連線池

Mysql學習--07.c3p0資料庫連線池

學習目標

C3p0資料庫連線池

一、c3p0資料庫連線池

         1、概述:

c3p0是一個開源的JDBC連線池、它實現了資料來源和JNDI(Java Naming and Directory Interface,Java命名和目錄介面)繫結、支援jdbc3和jdbc2的標準拓展、目前使用它的開源專案有Hibernate,Spring等c3p0 開發包下載: http://sourceforge.net

對比圖說明c3p0優點:

總結:節省建立連線與釋放連線的效能消耗 ---- 連線池中連線起到複用的作用,提高程式效能. 降低了資料庫的壓力.

2、配置c3p0

手動                

    // 核心連線池類

                   ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();

                   // 設定四個JDBC基本連線屬性

                   comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");

                   comboPooledDataSource.setJdbcUrl("jdbc:mysql:///day04");

                   comboPooledDataSource.setUser("root");

                   comboPooledDataSource.setPassword("123");

特別注意 : MySQL 驅動 8 版本之後關於 driverClass url 引數的書寫變化 :

com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=utf-8&useSSL=false

3、硬編碼、手動書寫配置引數

// 硬編碼 :
@Test
public void test1() throws PropertyVetoException {

    // 1. 建立了一個核心類物件 :
    ComboPooledDataSource dataSource = new ComboPooledDataSource();
    // DataSource dataSource = new ComboPooledDataSource();

    // 2. 設定了四個核心引數
    dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=UTF-8&useSSL=false");
    dataSource.setUser("root");
    dataSource.setPassword("123456");

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    for (int i = 0; i < 10; i++) {
        try {
            // 3. 獲取連線 (不要新建, 應該從連線池中直接獲取)
            conn = dataSource.getConnection();

            // 4. 操作資料
            String sql = "select * from user;";
            // 預編譯
            stmt = conn.prepareStatement(sql);
            // 直接執行
            rs = stmt.executeQuery();

            // 遍歷結果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                String email = rs.getString("email");
                // System.out.println(id + " : " + username + " : " + password + " : " + email);
            }

            System.out.println(i + " conn = " + conn);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 5. 釋放資源
            JDBCUtils.release(conn, stmt, rs);
        }
    }
}

4、軟編碼:配置檔案寫在xml中

src下新建c3p0-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<c3p0-config>
    <!-- 預設配置,c3p0框架預設載入這段預設配置 -->
    <default-config>
        <!-- 配置JDBC 四個基本屬性 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&amp;characterEncoding=utf-8&useSSL=false </property>
        <property name="user">root</property>
        <property name="password">ssw</property>
    </default-config>
    <!-- 可以自定義配置,為這段配置起一個名字,c3p0指定名稱載入配置 -->
    <named-config name="itcast">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&amp;characterEncoding=utf-8&useSSL=false</property>
        <property name="user">root</property>
        <property name="password">ssw</property>
    </named-config>
</c3p0-config>

常用基本連線池屬性

    acquireIncrement  如果連線池中連線都被使用了,一次性增長3個新的連線

    initialPoolSize  連線池中初始化連線數量 預設:3

    maxPoolSize      最大連線池中連線數量 預設:15連線

    maxIdleTime      如果連線長時間沒有使用,將被回收 預設:0 連線永不過期

minPoolSize      連線池中最小連線數量 預設:3

程式碼實現:

// 軟編碼 : 配置檔案
@Test
public void test2() throws PropertyVetoException {

    // 1. 建立了一個核心類物件 :
    // new ComboPooledDataSource(); 自動尋找一個檔案. 在 src 目錄下尋找 c3p0-config.xml 檔案.
    // 如果有, 自動載入該 xml 檔案中的資料, 如果沒有, 報錯.
    // DataSource dataSource = new ComboPooledDataSource("itcast");  // 名稱配置
    DataSource dataSource = new ComboPooledDataSource();  // 預設配置

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    for (int i = 0; i < 10; i++) {
        try {
            // 3. 獲取連線 (不要新建, 應該從連線池中直接獲取)
            conn = dataSource.getConnection();

            // 4. 操作資料
            String sql = "select * from user;";
            // 預編譯
            stmt = conn.prepareStatement(sql);
            // 直接執行
            rs = stmt.executeQuery();

            // 遍歷結果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                String email = rs.getString("email");
                // System.out.println(id + " : " + username + " : " + password + " : " + email);
            }

            System.out.println(i + " conn = " + conn);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 5. 釋放資源
            JDBCUtils.release(conn, stmt, rs);
        }
    }
}

5、最終版、將JDBCUtils工具類實現c3p0封裝(重點)

A、配置檔案:c3p0-config.xml 資料庫連線池配置檔案 : 需要建立在 src 目錄下.

<?xml version="1.0" encoding="UTF-8" ?>

<c3p0-config>
    <!-- 預設配置,c3p0框架預設載入這段預設配置 -->
    <default-config>
        <!-- 配置JDBC 四個基本屬性 -->
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&amp;characterEncoding=utf-8&useSSL=false </property>
        <property name="user">root</property>
        <property name="password">ssw</property>
    </default-config>
    <!-- 可以自定義配置,為這段配置起一個名字,c3p0指定名稱載入配置 -->
    <named-config name="itcast">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/user?serverTimezone=UTC&amp;characterEncoding=utf-8&useSSL=false</property>
        <property name="user">root</property>
        <property name="password">ssw</property>
    </named-config>
</c3p0-config>

B、c3p0工具類:

public class JDBCUtils {
    // 屬性 (資料)
    // 預設載入   位置: src    名稱: c3p0-config.xml 檔案.
    private static final DataSource dataSource = new ComboPooledDataSource();

    // 提供 : 給 dataSource 提供一個 getter 方法
    public static DataSource getDataSource() {
        return dataSource;
    }

    // 2. 獲取連線
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    // 3. 釋放資源
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null;
        }

        release(conn, stmt);
    }

    public static void release(Connection conn, Statement stmt) {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }

        if (conn != null) {
            try {
                conn.close();   // Spring AOP
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

C、測試類程式碼:

// JDBC 連線操作的程式碼
@Test
public void test3() {

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    for (int i = 0; i < 10; i++) {
        try {
            // 1. 獲取連線 (不要新建, 應該從連線池中直接獲取)
            conn = JDBCUtils.getConnection();

            // 2. 操作資料
            String sql = "select * from user;";
            // 預編譯
            stmt = conn.prepareStatement(sql);
            // 直接執行
            rs = stmt.executeQuery();

            // 遍歷結果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                String email = rs.getString("email");
                // System.out.println(id + " : " + username + " : " + password + " : " + email);
            }

            System.out.println(i + " conn = " + conn);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 3. 釋放資源
            JDBCUtils.release(conn, stmt, rs);
        }
    }
}

總結:上圖可以看到一個@5c7bfdc1 連線物件被使用多次。最終版是我們要記住的。其他只是個過程。