經典的java自定義資料庫連線池程式碼
import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Enumeration; import java.util.Vector; public class ConnectionPool { private String jdbcDriver = ""; // 資料庫驅動 private String dbUrl = ""; // 資料 URL private String dbUsername = ""; // 資料庫使用者名稱 private String dbPassword = ""; // 資料庫使用者密碼 private String testTable = ""; // 測試連線是否可用的測試表名,預設沒有測試表 private int initialConnections = 10; // 連線池的初始大小 private int incrementalConnections = 5;// 連線池自動增加的大小 private int maxConnections = 50; // 連線池最大的大小 private Vector connections = null; // 存放連線池中資料庫連線的向量 , 初始時為 null // 它中存放的物件為 PooledConnection 型 public ConnectionPool() { } /** * * 建構函式 * * @param jdbcDriver * String JDBC 驅動類串 * @param dbUrl * String 資料庫 URL * @param dbUsername * String 連線資料庫使用者名稱 * @param dbPassword * String 連線資料庫使用者的密碼 */ public ConnectionPool(String jdbcDriver, String dbUrl, String dbUsername, String dbPassword) { this.jdbcDriver = jdbcDriver; this.dbUrl = dbUrl; this.dbUsername = dbUsername; this.dbPassword = dbPassword; } /** * 建立一個數據庫連線池,連線池中的可用連線的數量採用類成員 initialConnections 中設定的值 */ public synchronized void createPool() throws Exception { // 確保連線池沒有建立 // 如果連線池己經建立了,儲存連線的向量 connections 不會為空 if (connections != null) { return; // 如果己經建立,則返回 } // 例項化 JDBC Driver 中指定的驅動類例項 Driver driver = (Driver) (Class.forName(this.jdbcDriver).newInstance()); DriverManager.registerDriver(driver); // 註冊 JDBC 驅動程式 // 建立儲存連線的向量 , 初始時有 0 個元素 connections = new Vector(); // 根據 initialConnections 中設定的值,建立連線。 createConnections(this.initialConnections); System.out.println(" 資料庫連線池建立成功! "); } /** * * 建立由 numConnections 指定數目的資料庫連線 , 並把這些連線 * * 放入 connections 向量中 * * @param numConnections * 要建立的資料庫連線的數目 */ @SuppressWarnings("unchecked") private void createConnections(int numConnections) throws SQLException { // 迴圈建立指定數目的資料庫連線 for (int x = 0; x < numConnections; x++) { // 是否連線池中的資料庫連線的數量己經達到最大?最大值由類成員 maxConnections // 指出,如果 maxConnections 為 0 或負數,表示連線數量沒有限制。 // 如果連線數己經達到最大,即退出。 if (this.maxConnections > 0 && this.connections.size() >= this.maxConnections) { break; } // add a new PooledConnection object to connections vector // 增加一個連線到連線池中(向量 connections 中) try { connections.addElement(new PooledConnection(newConnection())); } catch (SQLException e) { System.out.println(" 建立資料庫連線失敗! " + e.getMessage()); throw new SQLException(); } System.out.println(" 資料庫連線己建立 ......"); } } /** * * 建立一個新的資料庫連線並返回它 * * * * @return 返回一個新建立的資料庫連線 * */ private Connection newConnection() throws SQLException { // 建立一個數據庫連線 Connection conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword); // 如果這是第一次建立資料庫連線,即檢查資料庫,獲得此資料庫允許支援的 // 最大客戶連線數目 // connections.size()==0 表示目前沒有連線己被建立 if (connections.size() == 0) { DatabaseMetaData metaData = conn.getMetaData(); int driverMaxConnections = metaData.getMaxConnections(); // 資料庫返回的 driverMaxConnections 若為 0 ,表示此資料庫沒有最大 // 連線限制,或資料庫的最大連線限制不知道 // driverMaxConnections 為返回的一個整數,表示此資料庫允許客戶連線的數目 // 如果連線池中設定的最大連線數量大於資料庫允許的連線數目 , 則置連線池的最大 // 連線數目為資料庫允許的最大數目 if (driverMaxConnections > 0 && this.maxConnections > driverMaxConnections) { this.maxConnections = driverMaxConnections; } } return conn; // 返回建立的新的資料庫連線 } /** * * 通過呼叫 getFreeConnection() 函式返回一個可用的資料庫連線 , * * 如果當前沒有可用的資料庫連線,並且更多的資料庫連線不能建立(如連線池大小的限制),此函式等待一會再嘗試獲取。 * * @return 返回一個可用的資料庫連線物件 * */ public synchronized Connection getConnection() throws SQLException { // 確保連線池己被建立 if (connections == null) { return null; // 連線池還沒建立,則返回 null } Connection conn = getFreeConnection(); // 獲得一個可用的資料庫連線 // 如果目前沒有可以使用的連線,即所有的連線都在使用中 while (conn == null) { // 等一會再試 wait(250); conn = getFreeConnection(); // 重新再試,直到獲得可用的連線,如果 // getFreeConnection() 返回的為 null // 則表明建立一批連線後也不可獲得可用連線 } return conn;// 返回獲得的可用的連線 } /** * * 本函式從連線池向量 connections 中返回一個可用的的資料庫連線,如果 * * 當前沒有可用的資料庫連線,本函式則根據 incrementalConnections 設定 * * 的值建立幾個資料庫連線,並放入連線池中。 * * 如果建立後,所有的連線仍都在使用中,則返回 null * * @return 返回一個可用的資料庫連線 * */ private Connection getFreeConnection() throws SQLException { // 從連線池中獲得一個可用的資料庫連線 Connection conn = findFreeConnection(); if (conn == null) { // 如果目前連線池中沒有可用的連線 // 建立一些連線 createConnections(incrementalConnections); // 重新從池中查詢是否有可用連線 conn = findFreeConnection(); if (conn == null) { // 如果建立連線後仍獲得不到可用的連線,則返回 null return null; } } return conn; } /** * * 查詢連線池中所有的連線,查詢一個可用的資料庫連線, * * 如果沒有可用的連線,返回 null * * @return 返回一個可用的資料庫連線 * */ private Connection findFreeConnection() throws SQLException { Connection conn = null; PooledConnection pConn = null; // 獲得連線池向量中所有的物件 Enumeration enumerate = connections.elements(); // 遍歷所有的物件,看是否有可用的連線 while (enumerate.hasMoreElements()) { pConn = (PooledConnection) enumerate.nextElement(); if (!pConn.isBusy()) { // 如果此物件不忙,則獲得它的資料庫連線並把它設為忙 conn = pConn.getConnection(); pConn.setBusy(true); // 測試此連線是否可用 if (!testConnection(conn)) { // 如果此連線不可再用了,則建立一個新的連線, // 並替換此不可用的連線物件,如果建立失敗,返回 null try { conn = newConnection(); } catch (SQLException e) { System.out.println(" 建立資料庫連線失敗! " + e.getMessage()); return null; } pConn.setConnection(conn); } break; // 己經找到一個可用的連線,退出 } } return conn;// 返回找到到的可用連線 } /** * 測試一個連線是否可用,如果不可用,關掉它並返回 false 否則可用返回 true * * @param conn * 需要測試的資料庫連線 * @return 返回 true 表示此連線可用, false 表示不可用 */ private boolean testConnection(Connection conn) { try { // 判斷測試表是否存在 if (testTable.equals("")) { // 如果測試表為空,試著使用此連線的 setAutoCommit() 方法 // 來判斷連線否可用(此方法只在部分資料庫可用,如果不可用 , // 丟擲異常)。注意:使用測試表的方法更可靠 conn.setAutoCommit(true); } else { // 有測試表的時候使用測試表測試 // check if this connection is valid Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select count(*) from " + testTable); rs.next(); System.out.println(testTable + ":表的記錄數為:" + rs.getInt(1)); } } catch (SQLException e) { // 上面丟擲異常,此連線己不可用,關閉它,並返回 false; e.printStackTrace(); closeConnection(conn); return false; } // 連線可用,返回 true return true; } /** * 此函式返回一個數據庫連線到連線池中,並把此連線置為空閒。 * * 所有使用連線池獲得的資料庫連線均應在不使用此連線時返回它。 * * @param 需返回到連線池中的連線物件 */ public void returnConnection(Connection conn) { // 確保連線池存在,如果連線沒有建立(不存在),直接返回 if (connections == null) { System.out.println(" 連線池不存在,無法返回此連線到連線池中 !"); return; } PooledConnection pConn = null; Enumeration enumerate = connections.elements(); // 遍歷連線池中的所有連線,找到這個要返回的連線物件 while (enumerate.hasMoreElements()) { pConn = (PooledConnection) enumerate.nextElement(); // 先找到連線池中的要返回的連線物件 if (conn == pConn.getConnection()) { // 找到了 , 設定此連線為空閒狀態 pConn.setBusy(false); break; } } } /** * 重新整理連線池中所有的連線物件 */ public synchronized void refreshConnections() throws SQLException { // 確保連線池己創新存在 if (connections == null) { System.out.println(" 連線池不存在,無法重新整理 !"); return; } PooledConnection pConn = null; Enumeration enumerate = connections.elements(); while (enumerate.hasMoreElements()) { // 獲得一個連線物件 pConn = (PooledConnection) enumerate.nextElement(); // 如果物件忙則等 5 秒 ,5 秒後直接重新整理 if (pConn.isBusy()) { wait(5000); // 等 5 秒 } // 關閉此連線,用一個新的連線代替它。 closeConnection(pConn.getConnection()); pConn.setConnection(newConnection()); pConn.setBusy(false); } } /** * 關閉連線池中所有的連線,並清空連線池。 */ public synchronized void closeConnectionPool() throws SQLException { // 確保連線池存在,如果不存在,返回 if (connections == null) { System.out.println(" 連線池不存在,無法關閉 !"); return; } PooledConnection pConn = null; Enumeration enumerate = connections.elements(); while (enumerate.hasMoreElements()) { pConn = (PooledConnection) enumerate.nextElement(); // 如果忙,等 5 秒 if (pConn.isBusy()) { wait(5000); // 等 5 秒 } // 5 秒後直接關閉它 closeConnection(pConn.getConnection()); // 從連線池向量中刪除它 connections.removeElement(pConn); } // 置連線池為空 connections = null; } /** * 關閉一個數據庫連線 * * @param 需要關閉的資料庫連線 */ private void closeConnection(Connection conn) { try { conn.close(); } catch (SQLException e) { System.out.println(" 關閉資料庫連接出錯: " + e.getMessage()); } } /** * 使程式等待給定的毫秒數 * * @param 給定的毫秒數 */ private void wait(int mSeconds) { try { Thread.sleep(mSeconds); } catch (InterruptedException e) { } } /** * 返回連線池的初始大小 * * @return 初始連線池中可獲得的連線數量 */ public int getInitialConnections() { return this.initialConnections; } /** * 設定連線池的初始大小 * * @param 用於設定初始連線池中連線的數量 */ public void setInitialConnections(int initialConnections) { this.initialConnections = initialConnections; } /** * 返回連線池自動增加的大小 、 * * @return 連線池自動增加的大小 */ public int getIncrementalConnections() { return this.incrementalConnections; } /** * 設定連線池自動增加的大小 * * @param 連線池自動增加的大小 */ public void setIncrementalConnections(int incrementalConnections) { this.incrementalConnections = incrementalConnections; } /** * 返回連線池中最大的可用連線數量 * * @return 連線池中最大的可用連線數量 */ public int getMaxConnections() { return this.maxConnections; } /** * 設定連線池中最大可用的連線數量 * * @param 設定連線池中最大可用的連線數量值 */ public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; } /** * 獲取測試資料庫表的名字 * * @return 測試資料庫表的名字 */ public String getTestTable() { return this.testTable; } /** * 設定測試表的名字 * * @param testTable * String 測試表的名字 */ public void setTestTable(String testTable) { this.testTable = testTable; } /** * 內部使用的用於儲存連線池中連線物件的類 * * 此類中有兩個成員,一個是資料庫的連線,另一個是指示此連線是否 * * 正在使用的標誌。 */ class PooledConnection { Connection connection = null;// 資料庫連線 boolean busy = false; // 此連線是否正在使用的標誌,預設沒有正在使用 // 建構函式,根據一個 Connection 構告一個 PooledConnection 物件 public PooledConnection(Connection connection) { this.connection = connection; } // 返回此物件中的連線 public Connection getConnection() { return connection; } // 設定此物件的,連線 public void setConnection(Connection connection) { this.connection = connection; } // 獲得物件連線是否忙 public boolean isBusy() { return busy; } // 設定物件的連線正在忙 public void setBusy(boolean busy) { this.busy = busy; } } }
import java.sql.Connection; public class ConnectionPoolTest { public static void main(String[] args) throws Exception { ConnectionPool connPool = new ConnectionPool("oracle.jdbc.driver.OracleDriver","jdbc:oracle:thin:@127.0.0.1:1521:ORCL","scott","tiger"); connPool.createPool(); Connection conn = connPool.getConnection(); connPool.closeConnectionPool(); connPool.setTestTable("EMP"); } }
相關推薦
經典的java自定義資料庫連線池程式碼
import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.DriverManager; import j
自定義資料庫連線池實現方式 MySQL
應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中,常常用到阿里巴
自定義資料庫連線池實現方式 MySQL
應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中
(二十)自定義資料庫連線池
目錄 使用資料庫連線池優化資料庫效能 之前我們對資料庫的操作,其實是有很大問題的; 因為我們是每次操作資料庫之前,都會問資料庫要一個連線,用完之後,就把這個連結還給了資料庫; 其實資料庫連線是重量級的東西,資料庫每次建立一個連接出來,都要花
java資料庫連線池程式碼實現
import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.uti
java建立資料庫連線池程式碼
資料庫連線池(Connection pooling)是程式啟動時建立足夠的資料庫連線,並將這些連線組成一個連線池,由程式動態地對池中的連線進行申請,使用,釋放。 大家可以想一下,如果專案中沒有資料庫連線池會是一個什麼樣的結果?每訪問一次資料庫
Java 自定義線程池
dfa and hand blank epo cte 方法的參數 factor handler Java 自定義線程池 https://www.cnblogs.com/yaoxiaowen/p/6576898.html public ThreadPoolExecutor(i
JAVA基礎26-資料庫連線池
資料庫連線池 資料庫連線池負責分配,管理,釋放資料庫連線,它允許應用程式重複使用一個現有的資料庫連線,而不是重新建立一個。 編寫資料庫連線池 編寫資料庫連線池必須實現java.sql.DataSource介面 在Da
Tomcat9 + java + mysql 配置資料庫連線池
今天看到書上MyEclipse配置資料庫連線池,搞了好久不成功,上網Google了好久,先是自己手動部署網站,在網上看的都是把web.xml和context.xml放在WEB-INF資料夾下,怎麼也不
java自定義執行緒池--ThreadPoolExecutors
public class MyThreadPool { public static void main(String[] args) { /** * 1.在使用有界佇列的時候:若有新的任務需要執行,如果執行緒池實際執行緒數小於corePoolSize核心執行緒數的時候,則優先建立執行緒。
Java自定義執行緒池和執行緒總數控制
1 概述池化是常見的思想,執行緒池是非常典型的池化的實現,《Java併發程式設計實戰》也大篇幅去講解了Java中的執行緒池。本文實現一個簡單的執行緒池。 2 核心類 【1】介面定義 public interface IThreadPool<Job extends
Java中的資料庫連線池原理
連線池的基本工作原理 1、基本概念及原理 我們知道,對於共享資源,有一個很著名的設計模式:資源池(Resource Pool)。該模式正是為了解決資源的頻繁分配?釋放所造成的問題。資料庫連線池的基本思想就是為資料庫連線建立一個“緩衝池”。預先在緩衝池中放入一定數量的連
【CAS】自定義資料庫連線配置
在上一篇部落格中,對CAS進行了整體的介紹,我們知道,CAS可分為Server和Client。本篇部落格開始介紹對CAS Sever進行的一些自定義配置。 【版本說明】:CAS Server 4.0 【下載地址】:https://github.com/aper
各種Java技術框架資料庫連線池比較(一)
<c3p0-config> <default-config> <!--當連線池中的連線耗盡的時候c3p0一次同時獲取的連線數。Default: 3 --> <property name="acquireIncrement">3</property>
Java自學-JDBC 資料庫連線池
## 資料庫連線池 與[執行緒池](http://how2j.cn/k/thread/thread-threadpool/357.html?p=43278)類似的,資料庫也有一個數據庫連線池。 不過他們的實現思路是不一樣的。 本章節講解了自定義資料庫連線池類:ConnectionPool,雖然不是很完善和
自定義實現資料庫連線池
資料庫連線池: >資料庫的連線物件建立工作,比較消耗效能 >一開始先在記憶體中開闢一塊空間(集合) , 先往池子裡面放置 多個連線物件。 後面需要連線的話,直接從池子裡面去。不要去自己建立連線了。 使用完畢, 要記得歸還連線。確保連線物件能迴圈利用。即建立
【Java】Spring和Tomcat自帶的連線池實現資料庫操作
@[toc] 前言 前面我們已經用Spring和傳統的Jdbc實現資料庫操作、Spring和JdbcTemplate實現資料庫操作。但是這些都是基於直連的資料來源進行的,現在我們將介紹基於連線池的資料來源進行資料庫操作。前面幾個步驟都相同。 建立資料庫 首先建立我們的資料庫(這裡我使用的是Mysql)
Javaweb總結2—自定義JDBC資料庫連線池
什麼是資料庫連線池呢? 資料庫連線池簡而言之就是一個容器裡存放一些資料庫連線。 那問題來了,要資料庫連線池有什麼用呢? 哈哈不用急,接下來我們一起慢慢分析分析 我們仔細觀察這個連線池,有沒有解決剛剛開始的疑問呢? 實現連線池先繼承一個DataSourse類,當然也可以選擇不繼承它來寫
Druid連線池自定義資料庫密碼加解密的實現
Druid的功能 1、替換DBCP和C3P0。Druid提供了一個高效、功能強大、可擴充套件性好的資料庫連線池。 2、可以監控資料庫訪問效能,Druid內建提供了一個功能強大的StatFilter外掛,能夠詳細統計SQL的執行效能,這對於線上分析資料庫訪問效
java自定義連線池
1、java自定義連線池 1.1連線池的概念: 實際開發中"獲取連線"或“釋放資源”是非常消耗系統資源的兩個過程,為了姐姐此類效能問題,通常情況我們採用連線池技術來貢獻連線Connection 用池來管理Connection,這樣可以重複使用Connection,有了池,所以我們就不用自