JDBC連接------C3P0連接池

JDBC連接------C3P0連接池

目錄

1、爲什麼要用到連接池

2、連接池原理

3、C3P0連接池

總結


1、爲什麼要用到連接池

當一個用戶要訪問某個網站時,就需要頻繁的使用數據庫進行增刪改查,每次增刪改查操作都需要獲取連接,如果說一個用戶的頻繁獲取連接系統尚能接受,那麼成千上萬的用戶瀏覽這個網站進行增刪改查來獲取連接 對系統來說將是一個巨大的負荷!爲了解決這一問題,我們可以設計一個用來存放連接的池子,這個池子起名爲連接池。連接池中存放一定數量的連接,當用戶需要獲取連接時,就從這個池子中獲取,用完後關閉資源,再將連接放回連接池。如此,一個連接就可以被反覆使用,大大降低系統的壓力解決了建立數據庫連接耗費資源和時間很多的問題,提高了性能。

2、連接池原理

具體的代碼實現連接池此處不作贅述,只簡單解釋下連接池的拿連接·和還連接的原理。

市面上常用的連接池有很多,DBCP 、C3P0、BoneCP、Proxool、DDConnectionBroker、DBPool、XAPool、Primrose、SmartPool、MiniConnectionPoolManager及Druid等。Java爲數據庫連接池提供了公共的接口:javax.sql.DataSource ,各個廠商需要讓自己的連接池實現這個接口。這也大大減小了程序員的開發成本。

連接池其實就是一個需要頻繁拿連接,還連接的大容器。說白了連接池就是一個集合List<Connection>(因爲是頻繁的取還元素,所以這裏集合更適合是LinkedList)。當用戶訪問時,先向容器中放入多個連接,當用戶使用時,將連接獲取出去,獲取時連接就要從連接池中被拿走,此處用remove方法獲取(不可以用get方法獲取連接),remove方法返回值就是移除的內容,待用戶使用完畢後,再將連接放回去(add)。這樣即實現了連接池額功能,可以讓集合中的連接反覆使用,不需要多次創建新的連接。 

3、C3P0連接池

C3P0連接池因爲其配置簡單,持續運行的穩定性很不錯,在大併發量下的穩定性也有一定保證的優良特性,受到廣大用戶的歡迎。使用C3P0連接池需要用到架包和配置文件,需要配置文件和架包可以點擊下面連接。

C3P0用到的jar包和配置文件

配置文件爲固定格式的XML文件c3p0-config.xml(3-1),配置文件必須放在項目的src文件夾下面,創建C3P0連接池後會被自動解析。

 <c3p0-config>
   <!-- 使用默認的配置讀取連接池對象 -->
   <default-config>
     <!--  連接參數 -->
<!--驅動 -->
     <property name="driverClass">com.mysql.jdbc.Driver</property>
<!--連接 -->
     <property name="jdbcUrl">jdbc:mysql://localhost:3306/day03</property>
<!--用戶名 -->
     <property name="user">root</property>
<!-- 密碼-->
     <property name="password">root</property>

     <!-- 連接池參數 -->
<!-- 初始化連接池連接數-->
     <property name="initialPoolSize">5</property>
<!--連接池內最大連接數 -->
     <property name="maxPoolSize">10</property>
<!--最大等待時間 -->
     <property name="checkoutTimeout">2000</property>
<!--最大空閒回收時間 -->
     <property name="maxIdleTime">1000</property>
   </default-config>
 </c3p0-config>

通過C3P0獲取連接同樣寫在一個工具類裏面,和前面原生方法獲取連接的工具類基本一致,不同的是此處獲取連接是在連接池中獲取。代碼如下(3-2)

package teacher.com.itheima.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;

/*
    通過getConnection方法 從連接池中 獲取到java.sql.Connection接口的實現類對象
    JDK提供了一個連接池的接口 java.sql.DataSource
            方法
                Connection getConnection() 從連接池中獲取到連接對象
    要想調用這個方法 就需要DataSource實現類對象 C3P0連接池實現了此接口
    ComboPooledDataSource類實現了 DataSource接口 我們只需要創建這個類的對象
    調用getConnection方法就是從連接池中獲取了連接



 */
public class C3P0Utils {

    //先私有化連接池變量
    private static ComboPooledDataSource ds ;
//工具類固有寫法,私有化構造方法
    private C3P0Utils(){} 
//在靜態代碼塊中創建連接池
    static{
        try{
            //創建連接池後會自動讀取並解析項目的src目錄下的c3p0-config.xml配置文件並自動的加載驅動
            ds = new ComboPooledDataSource();
            //對連接池進行配置,此處配置和配置文件的配置完全一樣,是配置連接池的另一種方式,
            // 兩種配置方式取其一即可,一般用配置文件
            // 在已經有配製文件的情況下會優先解析此處java代碼的配置。
            //此處配置和
//            ds.setDriverClass("com.mysql.jdbc.Driver");
//            ds.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/day04");
//            ds.setUser("root");
//            ds.setPassword("root");


            //可選配置
//            ds.setInitialPoolSize(10);
            //最大連接數
//            ds.setMaxPoolSize(100);
            //最大等待時間
//            ds.setCheckoutTimeout(10000);
            //最大空閒回收時間
//            ds.setMaxIdleTime(1000000);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    //獲取連接池對象 在後面是有DBUtils時會用到
    public static DataSource getDataSouce(){
        return ds;
    }




    //從連接池中獲取連接對象
    public static Connection getConnection() throws SQLException {
        Connection con = ds.getConnection();//實現類對象
        return con;
    }


    //關閉資源,雖然是close但是是還回連接到連接池中
    public static void close(Connection con, Statement stat, ResultSet rs){
        try {
            if(con!=null)
                con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(stat!=null)
                stat.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(rs!=null)
                rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

至此,一個使用C3P0創建連接池,獲取連接的工具類已經完成,後面調用連接只需要通過C3P0.getConnection()的方法調用即可(3-3),和原生JDBC連接調用工具類的方法一樣。

package teacher.com.itheima03;

import teacher.com.itheima.bean.User;
import teacher.com.itheima.utils.C3P0Utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/*
    查詢users表中所有數據
    將每條數據封裝到一個USer對象中
    將對象放入一個list集合中
 */
public class Test_C3P0Utils {
    public static void main(String[] args) throws SQLException {
        //根據c3p0工具類獲取連接對象
        Connection con = C3P0Utils.getConnection();
        //根據連接獲取執行sql語句對象
        String sql = "select * from students";
        PreparedStatement ps = con.prepareStatement(sql);
        //執行sql語句;
        ResultSet rs = ps.executeQuery();
        //定義一個集合 遍歷結果集 獲取內容
        List<User> list = new ArrayList<>();

        while(rs.next()){
            int stuid = rs.getInt("stuid");
            String stu_name = rs.getString("stu_name");
            int classid = rs.getInt("classid");
            String sex = rs.getString("sex");
            int book = rs.getInt("book");
            // //將數據封裝到User對象中
            User u = new User(stuid,stu_name,classid,sex,book);
            ////將User對象添加到集合中
            list.add(u);
        }
        System.out.println(list);
        //關閉資源
        C3P0Utils.close(con,ps,rs);
//        con.close();
    }
}

總結

C3P0創建連接池獲取連接的方法解決了用戶頻繁獲取連接對系統資源造成的浪費,但是Test_C3P0Utils類中調用工具類獲取連接執行sql的代碼過於繁雜的情況依然存在,下一篇文章會利用工具類DBUtils來對這些操作進行簡化。

能力尚淺,有待進步,如有不足,不吝賜教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章