1. 程式人生 > 實用技巧 >C3P0與Druid資料庫連線池總結

C3P0與Druid資料庫連線池總結

目錄

C3P0連線池

步驟:

  1. 導c3p0的jar包
  2. 建立配置檔案並配置
  3. 建立核心物件 ComboPooledDataSource
  4. 獲取連線 getConnection

C3P0初始化:

  • 先匯入兩個包:(MySQL的驅動要確保已經匯入,否則用不了)

    • c3p0-0.9.5.2.jar
    • mchange-commons-java-0.2.12.jar
  • 建立配置檔案:

    • 在src目錄下直接建立C3P0的配置檔案,檔案可以是c3p0-config.xml或c3p0.properties(檔名及副檔名一定要一樣,否則識別不了)

      使用這兩種方式進行配置時,只要將配置好的檔案放入classpath資料夾下即可,在java程式碼當中不用顯示的給出訪問配置方式的程式碼,c3p0會自動識別

    • c3p0-config.xml:

      <?xml version="1.0" encoding="UTF-8" ?>
      <c3p0-config>
          <!-- 使用預設的配置讀取連線池物件 -->
          <default-config>
              <!-- 連線引數 -->
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3306/databaseName</property>
              <property name="user">root</property>
              <property name="password">admin</property>
              <!-- 連線池引數 -->
              <!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數-->
      		<property name="acquireIncrement">3</property>
              <!-- 關閉自動提交 -->
              <property name="autoCommitOnClose">false</property>
              <property name="initialPoolSize">5</property>
              <property name="minPoolSize">2</property>
              <property name="maxPoolSize">10</property>   
      		<!-- 最大等待時間 -->
              <property name="checkoutTimeout">3000</property>
              <!-- 最大空閒回收時間 -->
              <property name="maxIdleTime">1000</property>
          </default-config>
          
          <!-- 使用自定義的配置讀取連線池物件,如果要使用named-config裡面配置初始化資料來源,則只要使用一個帶引數的ComboPooledDataSource構造器就可以了 -->
          <named-config name="oracle">
              <!-- 連線引數 -->
              <property name="driverClass">com.mysql.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://localhost:3306/databaseName</property>
              <property name="user">root</property>
              <property name="password">admin</property>
      
              <!-- 連線池引數 -->
              <property name="initialPoolSize">5</property>
              <property name="maxPoolSize">8</property>
              <property name="checkoutTimeout">1000</property>
          </named-config>
      </c3p0-config>
      
    • c3p0.properties:

      #連線引數
      c3p0.jdbcUrl=jdbc:mysql://localhost:3306/databaseName
      c3p0.driverClass=com.mysql.jdbc.Driver
      c3p0.user=root
      c3p0.password=admin
      #連線池引數
      c3p0.acquireIncrement=3
      c3p0.autoCommitOnClose=false
      c3p0.initialPoolSize=5
      c3p0.minPoolSize=2
      c3p0.maxPoolSize=10
      c3p0.checkoutTimeout=3000
      c3p0.maxIdleTime=1000
      
    • 通過setters方法一個個地設定各個配置項(不推薦):

      ComboPooledDataSource cpds = new ComboPooledDataSource();    
      cpds.setDriverClass("com.mysql.jdbc.Driver");    
      cpds.setJdbcUrl("jdbc:mysql:///users");    
      cpds.setUser("root");    
      cpds.setPassword("admin");
      

建立C3P0工具類:

package top.linzeliang.web.dataSource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class C3P0Util {

    private static DataSource ds = null;

    static {
        //僅僅在類被載入時系統建立一個連線池,自動識別配置檔案
        ds = new ComboPooledDataSource();
    }

    public static Connection getConnection() {
        try {
            //獲取一個連線,已經存在的
            return ds.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println("獲取連線失敗!");
            return null;
        }
    }

    public static void closeConnection(Statement stmt, Connection conn) {

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                //將連線返回連線池
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

建立C3P0測試類:

package top.linzeliang.web.dataSource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*;

public class C3P0Demo {

    @Test
    public void test() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String sql = "CREATE TABLE user(id INT NOT NULL, username VARCHAR(18) NOT NULL, password VARCHAR(16) NOT NULL, PRIMARY KEY (id))";

        try {
            conn = C3P0Util.getConnection();
            pstmt = conn.prepareStatement(sql);
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            C3P0Util.closeConnection(pstmt, conn);
        }
    }
}

好了,這就是C3P0的基本使用了


Druid連線池(由阿里巴巴提供的資料庫連線池實現技術)

步驟:

  1. 導包
  2. 建立定義配置檔案
  3. 載入配置檔案
  4. 獲取資料庫連線池物件,通過工廠來獲取DruidDataSourceFactory
  5. 獲取連線 getConnection

Druid初始化:

  • 同樣,先匯入包:(MySQL的驅動也要確保匯入)

    • druid-1.1.23.jar
  • 建立配置檔案:

    • 要以properties字尾名結尾,我的是 druid.properties

      • druid.properties

        driverClassName=com.mysql.jdbc.Driver //驅動載入
        url=jdbc:mysql://127.0.0.1:3306/student?characterEncoding=utf-8 //註冊驅動
        username=root //連線資料庫的使用者名稱
        password=admin //連線資料庫的密碼。
        filters=stat //屬性型別的字串,通過別名的方式配置擴充套件外掛, 監控統計用的stat 日誌用log4j 防禦sql注入:wall
        initialSize=2 //初始化時池中建立的物理連線個數。
        maxActive=300 //最大的可活躍的連線池數量
        maxWait=60000 //獲取連線時最大等待時間,單位毫秒,超過連線就會失效。配置了maxWait之後,預設啟用公平鎖,併發效率會有所下降, 如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
        timeBetweenEvictionRunsMillis=60000 // 連接回收器的執行週期時間,時間到了清理池中空閒的連線,testWhileIdle根據這個判斷
        minEvictableIdleTimeMillis=300000
        validationQuery=SELECT 1 //用來檢測連線是否有效的sql,要求是一個查詢語句。
        testWhileIdle=true //建議配置為true,不影響效能,並且保證安全性。 申請連線的時候檢測,如果空閒時間大於timeBetweenEvictionRunsMillis, 執行validationQuery檢測連線是否有效。
        testOnBorrow=false //申請連線時執行validationQuery檢測連線是否有效,做了這個配置會降低效能。設定為false
        testOnReturn=false //歸還連線時執行validationQuery檢測連線是否有效,做了這個配置會降低效能,設定為flase
        poolPreparedStatements=false //是否快取preparedStatement,也就是PSCache。
        maxPoolPreparedStatementPerConnectionSize=200 // 池中能夠緩衝的preparedStatements語句數量
        
    • 可以放在任意位置(通過反射來獲取該檔案)

    • 載入配置檔案:

      //載入配置檔案
      Properties pro = new Properties();
      InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
      pro.load(is);
      //獲取連線物件
      DataSource ds = DruidDataSourceFactory.createDataSource(pro);
      //獲取連線
      Connection conn = ds.getConnection();
      

建立Druid工具類:

package top.linzeliang.web.dataSource.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.io.InputStream;
import java.sql.Connection;

public class DruidUtil {
    private static DataSource ds = null;
    static {
        try {
            //載入配置檔案
            Properties pro = new Properties();
            InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            //獲取連線物件
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        try {
            return ds.getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println("獲取連線失敗");
            return null;
        }
    }

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

        if (conn != null) {
            try {
                //將連線返回給連線池
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

建立Druid測試類:

package top.linzeliang.web.dataSource.druid;

import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DruidDemo {

    @Test
    public void test() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String sql = "UPDATE product SET product_name=? WHERE product_id=?";

        try {
            conn = DruidUtil.getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "6666");
            pstmt.setString(2, "0009");
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DruidUtil.closeConnection(pstmt, conn);
        }
    }
}

Spring JDBC

Spring JDBC:Spring框架對JDBC的簡單封裝。提供了一個JDBCTemplate物件簡化JDBC的開發

步驟:

  1. 導包:
    • commons-logging-1.2.jar
    • spring-beans-5.1.5.RELEASE.jar
    • spring-core-5.1.5.RELEASE.jar
    • spring-jdbc-5.1.5.RELEASE.jar
    • spring-tx-5.1.5.RELEASE.jar
  2. 建立JdbcTemplate物件(依賴於DataSource物件):
    • JdbcTemplate template = new JdbcTemplate(dataSource)
  3. 呼叫JdbcTemplate的方法來完成CRUD操作

常用方法:

  • update():執行DML語句,及對資料的增、刪、改(查是DQL語句)
  • queryForMap():將結果集封裝為Map集合,將列名作為key、值作為value將這條記錄封裝為一個Map集合(這個方法查詢的結果集長度只能是1
  • queryForList():將結果集封裝為List集合(是將每一條記錄封裝為一個Map集合,再將Map集合裝載到List集合中
  • query():將結果封裝為JavaBean物件
    • query的引數:RowMapper
      • 一般我們使用BeanPropertyRowMapper實現類。可以完成資料到JavaBean的自動封裝
      • new BeanPropertyRowMapper<型別>(型別.class)
  • queryForObject():將結果封裝為物件(一般用於聚合函式的查詢