連接池出現的背景:
數據庫連接是一種關鍵的、有限的、昂貴的資源,這一點在多用戶的網頁應用程序中體現得尤為突出。對數據庫連接的管理能顯著影響到整個應用程序的伸縮性和健壯性,影響到程序的性能指標。數據庫連接池正是針對這個問題提出來的。
數據量少的情況:
每一次web請求都要建立一次數據庫連接。建立連接是一個費時的活動,每次都得花費0.05s~1s的時間,而且系統還要分配內存資源。這個時間對於一次或幾次數據庫操作,或許感覺不出系統有多大的開銷。如下面的用戶查詢案例,如果同時有1000人訪問,就會不斷的有數據庫連接、斷開操作:
“數據庫連接”是一種稀缺的資源,為了保障網站的正常使用,應該對其進行妥善管理。其實我們查詢完數據庫后,如果不關閉連接,而是暫時存放起來,當別人使用時,把這個連接給他們使用。就避免了一次建立數據庫連接和斷開的操作時間消耗。原理如下:
我們自己嘗試開發一個連接池,來為上面的查詢業務提供數據庫連接服務:
① 編寫class 實現DataSource 接口
② 在class構造器一次性創建10個連接,將連接保存LinkedList中
③ 實現getConnection 從 LinkedList中返回一個連接
④ 提供將連接放回連接池中方法
1、連接池代碼
public class MySelfDataSource implements DataSource {
//鏈表 --- 實現棧結構,鏈表結構方便插入跟刪除操作 private LinkedList<Connection> dataSources = new LinkedList<Connection>(); //初始化連接數量 public MySelfDataSource() { //一次性創建10個連接 for(int i = 0; i < 10; i++) { try { //1、裝載Oracle驅動對象,作用是:
1、裝載。將字節碼讀入內存,並產生一個與之對應的java.lang.Class類對象
2、連接。這一步會驗證字節碼,為static變量分配內存,並賦默認值(0或null),並可選的解析符號引用(這里不理解沒關系)
3、初始化。為類的static變量賦初始值,假如有static int a = 1;這個將a賦值為1的操作就是這個時候做的。除此之外,還要調用類的static塊。(這一步是要點) Class.forName("oracle.jdbc.OracleDriver");// 或者使用DriverManager.registerDriver(new OracleDriver());
//2、通過JDBC建立數據庫連接 Connection con =DriverManager.getConnection( "jdbc:oracle:thin:@10.148.3.20:1521:tgtest", "saa", "123"); //3、將連接加入連接池中 dataSources.add(con); } catch (Exception e) { e.printStackTrace(); } } } @Override publicConnection getConnection() throws SQLException { //取出連接池中一個連接 finalConnection conn = dataSources.removeFirst(); // 刪除第一個連接返回 return conn; } //將連接放回連接池 publicvoid releaseConnection(Connection conn) { dataSources.add(conn); } }
2.使用連接池重構我們的用戶查詢函數
//查詢所有用戶 Public void FindAllUsers(){ //1、使用連接池建立數據庫連接 MyDataSource dataSource = new MyDataSource(); Connection conn =dataSource.getConnection(); //2、創建狀態 Statement state =con.createStatement(); //3、查詢數據庫並返回結果 ResultSet result =state.executeQuery("select * from users"); //4、輸出查詢結果 while(result.next()){ System.out.println(result.getString("email")); } //5、斷開數據庫連接 result.close(); state.close(); //6、歸還數據庫連接給連接池 dataSource.releaseConnection(conn); }
影響因素:
數據庫連接池在初始化時將創建一定數量的數據庫連接放到連接池中,這些數據庫連接的數量是由最小數據庫連接數制約。無論這些數據庫連接是否被使用,連接池都將一直保證至少擁有這么多的連接數量。連接池的最大數據庫連接數量限定了這個連接池能占有的最大連接數,當應用程序向連接池請求的連接數超過最大連接數量時,這些請求將被加入到等待隊列中。數據庫連接池的最小連接數和最大連接數的設置要考慮到下列幾個因素:
原理:
連接池基本的思想是在系統初始化的時候,將數據庫連接作為對象存儲在內存中,當用戶需要訪問數據庫時,並非建立一個新的連接,而是從連接池中取出一個已建立的空閑連接對象。使用完畢后,用戶也並非將連接關閉,而是將連接放回連接池中,以供下一個請求訪問使用。而連接的建立、斷開都由連接池自身來管理。同時,還可以通過設置連接池的參數來控制連接池中的初始連接數、連接的上下限數以及每個連接的最大使用次數、最大空閑時間等等。也可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。
作用:它大大提供了數據庫連接的利用率,減小了內存吞吐的開銷。
Java連接池:
-
支持多個pool
-
自動關閉相關聯的JDBC對象
-
在所設定time-outs之后察覺連接泄漏
-
追蹤連接使用情況
-
強制啟用最近最少用到的連接
-
把SmartPool“包裝”成現存的一個pool
-
Oracle的PS Cache內存占用優化
-
MySql的ping檢測優化