day48-JDBC和連接池04

JDBC和連接池0410.數據庫連接池10.1傳統連接弊端分析

  • 傳統獲取Connection問題分析
  1. 傳統的 JDBC 數據庫連接使用DriverManager來獲取,每次向數據庫建立連接的時候都要將Connection加載到內存中,再驗證IP地址 , 用戶名和密碼(約0.05s~1s時間) 。需要數據庫連接的時候,就向數據庫要求一個,頻繁地進行數據庫連接操作將會占用很多的系統資源,容易造成服務器崩潰
  2. 每一次數據庫連接,使用完后都得斷開,如果程序出現異常而未能關閉,將導致數據庫內存泄漏,最終將導致重啟數據庫
  3. 傳統獲取連接的方式,不能控制創建的連接數量 , 如連接過多,也可能導致內存泄漏,MySQL崩潰
  4. 解決傳統開發中的數據庫連接問題,可以采用數據庫連接池技術(connection pool)

day48-JDBC和連接池04

文章插圖
例子1
package li.jdbc.datasource;import li.jdbc.utils.JDBCUtils;import org.junit.Test;import java.sql.Connection;public class ConQuestion {@Testpublic void testCon(){for (int i = 0; i < 5000; i++) {//使用傳統的jdbc方式得到連接Connection connection = JDBCUtils.getConnection();//這里做一些工作....//不關閉連接資源 , 使其一直占用}}}出現的異常:
java.lang.RuntimeException: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
day48-JDBC和連接池04

文章插圖
例子2:
package li.jdbc.datasource;import li.jdbc.utils.JDBCUtils;import org.junit.Test;import java.sql.Connection;public class ConQuestion {@Testpublic void testCon(){long start = System.currentTimeMillis();System.out.println("開始連接...");for (int i = 0; i < 5000; i++) {//使用傳統的jdbc方式得到連接Connection connection = JDBCUtils.getConnection();//這里做一些工作....JDBCUtils.close(null,null,connection);//每次連接完都正常關閉連接資源}long end = System.currentTimeMillis();System.out.println("傳統方式連接5000次耗時:"+(end-start));//20171ms}}每次連接完都正常關閉連接資源,可以看到5000次連接數據庫需要耗時20171ms
day48-JDBC和連接池04

文章插圖
10.2數據庫連接池原理
  • 數據庫連接池基本介紹
  1. 預先在緩沖池中放入一定數量的連接,當需要建立數據庫連接時,只需從“緩沖池”中取出一個,使用完畢之后再將連接放回連接池中 。
  2. 數據庫連接池負責分配、管理和釋放數據庫連接 , 它允許應用程序重復使用一個現有的數據庫連接,而不是重新建立一個
  3. 當應用程序向連接池請求的連接數超過最大連接數量時 , 這些請求將被加入到等待隊列中
【day48-JDBC和連接池04】
day48-JDBC和連接池04

文章插圖
  • 數據庫連接池種類
  1. JDBC的數據庫連接池使用javax.sql.DataSource來表示,DataSource只是一個接口 , 該接口通常由第三方提供實現 [提供相應的jar包]
  2. C3P0數據庫連接池,速度相對較慢,穩定性不錯(hibernate,spring)
  3. DBCP數據庫連接池,速度相對C3P0較快,但不穩定
  4. Proxool數據庫連接池 , 有監控連接池狀態的功能 , 穩定性較C3P0差一點
  5. BoneCP數據庫連接池,速度快
  6. Druid(德魯伊)是阿里提供的數據庫連接池,集DBCP、C3P0、Proxool優點于一身的數據庫連接池
10.3C3P0方式10.3.1方式1-相關參數在程序中指定使用代碼實現c3p0數據庫連接池
首先在網上下載c3p0jar包 , 并將其復制到項目的lib文件夾中,右鍵選擇add as library
day48-JDBC和連接池04

文章插圖
day48-JDBC和連接池04

文章插圖
package li.jdbc.datasource;import com.mchange.v2.c3p0.ComboPooledDataSource;import org.junit.Test;import java.io.FileInputStream;import java.sql.Connection;import java.util.Properties;/** * 演示c3p0的使用 */public class C3P0_ {//方式1:相關參數在程序中指定,user,url , password等@Testpublic void testC3P0_01() throws Exception {//1.創建一個數據源對象ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();//2.通過配置文件mysql.properties獲取相關的連接信息Properties properties = new Properties();properties.load(new FileInputStream("src\\mysql.properties"));//讀取相關的屬性值String user = properties.getProperty("user");String password = properties.getProperty("password");String url = properties.getProperty("url");String driver = properties.getProperty("driver");//給數據源 comboPooledDataSource設置相關的參數//注意:連接管理 是由comboPooledDataSource來管理comboPooledDataSource.setDriverClass(driver);comboPooledDataSource.setJdbcUrl(url);comboPooledDataSource.setUser(user);comboPooledDataSource.setPassword(password);//設置初始化連接數comboPooledDataSource.setInitialPoolSize(10);//最大連接數--連接請求超過最大連接數據將進入等待隊列comboPooledDataSource.setMaxPoolSize(50);//測試連接池的效率long start = System.currentTimeMillis();for (int i = 0; i < 5000; i++) {Connection connection = comboPooledDataSource.getConnection();//這個方法就是從DataSource 接口實現的//System.out.println("連接成功");connection.close();}long end = System.currentTimeMillis();System.out.println("c3p0 5000次連接mysql 耗時=" + (end - start));}}

推薦閱讀