生活随笔
收集整理的這篇文章主要介紹了
Java 连接池的工作原理
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
什么是連接?
連接,是我們的編程語言與數(shù)據(jù)庫交互的一種方式。我們經(jīng)常會聽到這么一句話“數(shù)據(jù)庫連接很昂貴“。
有人接受這種說法,卻不知道它的真正含義。因此,下面我將解釋它究竟是什么。[如果你已經(jīng)知道了,你可以跳到它的工作原理部分]
創(chuàng)建連接的代碼片段:
| 1 | String connUrl = "jdbc:mysql://your.database.domain/yourDBname"; |
| 2 | Class.forName("com.mysql.jdbc.Driver"); |
| 3 | Connection con = DriverManager.getConnection (connUrl); |
當(dāng)我們創(chuàng)建了一個Connection對象,它在內(nèi)部都執(zhí)行了什么:
1.“DriverManager”檢查并注冊驅(qū)動程序,
2.“com.mysql.jdbc.Driver”就是我們注冊了的驅(qū)動程序,它會在驅(qū)動程序類中調(diào)用“connect(url…)”方法。
3.com.mysql.jdbc.Driver的connect方法根據(jù)我們請求的“connUrl”,創(chuàng)建一個“Socket連接”,連接到IP為“your.database.domain”,默認(rèn)端口3306的數(shù)據(jù)庫。
4.創(chuàng)建的Socket連接將被用來查詢我們指定的數(shù)據(jù)庫,并最終讓程序返回得到一個結(jié)果。
為什么昂貴?
現(xiàn)在讓我們談?wù)劄槭裁凑f它“昂貴“。
如果創(chuàng)建Socket連接花費的時間比實際的執(zhí)行查詢的操作所花費的時間還要更長。
這就是我們所說的“數(shù)據(jù)庫連接很昂貴”,因為連接資源數(shù)是1,它需要每次創(chuàng)建一個Socket連接來訪問DB。
因此,我們將使用連接池。
連接池初始化時創(chuàng)建一定數(shù)量的連接,然后從連接池中重用連接,而不是每次創(chuàng)建一個新的。
怎樣工作?
接下來我們來看看它是如何工作,以及如何管理或重用現(xiàn)有的連接。
我們使用的連接池供應(yīng)者,它的內(nèi)部有一個連接池管理器,當(dāng)它被初始化:
1.它創(chuàng)建連接池的默認(rèn)大小,比如指定創(chuàng)建5個連接對象,并把它存放在“可用”狀態(tài)的任何集合或數(shù)組中。
例如,代碼片段:
| 02 | ??String connUrl = "jdbc:mysql://your.database.domain/yourDBname"; |
| 03 | ??String driver = "com.mysql.jdbc.Driver"; |
| 04 | ??private Map<java.sql.Connection, String> connectionPool = null; |
| 05 | ??private void initPool() { |
| 07 | ??????connectionPool = new HashMap<java.sql.Connection, String>(); |
| 08 | ??????Class.forName(driver); |
| 09 | ??????java.sql.Connection con = DriverManager.getConnection(dbUrl); |
| 10 | ??????for (int poolInd = poolSize; poolInd < 0; poolInd++) { |
| 11 | ????????connectionPool.put(con, "AVAILABLE"); |
2.當(dāng)我們調(diào)用connectionProvider.getConnection(),然后它會從集合中獲取一個連接,當(dāng)然狀態(tài)也會更改為“不可用”。
例如,代碼片段:
| 02 | ??public java.sql.Connection getConnection() throws ClassNotFoundException, SQLException |
| 04 | ??????boolean isConnectionAvailable = true; |
| 05 | ??????for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) { |
| 06 | ??????????synchronized (entry) { |
| 07 | ??????????????if (entry.getValue()=="AVAILABLE") { |
| 08 | ??????????????????entry.setValue("NOTAVAILABLE"); |
| 09 | ??????????????????return (java.sql.Connection) entry.getKey(); |
| 11 | ??????????????isConnectionAvailable = false; |
| 14 | ??????if (!isConnectionAvailable) { |
| 15 | ??????????Class.forName(driver); |
| 16 | ??????????java.sql.Connection con = DriverManager.getConnection(connUrl); |
| 17 | ??????????connectionPool.put(con, "NOTAVAILABLE"); |
3.當(dāng)我們關(guān)閉得到的連接,ConnectionProvider是不會真正關(guān)閉連接。相反,只是將狀態(tài)更改為“AVAILABLE”。
例如,代碼片段:
| 02 | public void closeConnection(java.sql.Connection connection) throws ClassNotFoundException, SQLException { |
| 03 | ????for (Entry<java.sql.Connection, String> entry : connectionPool.entrySet()) { |
| 04 | ????????synchronized (entry) { |
| 05 | ????????????if (entry.getKey().equals(connection)) { |
| 06 | ????????????????//Getting Back the conncetion to Pool |
| 07 | ????????????????entry.setValue("AVAILABLE"); |
基本上連接池的實際工作原理就是這樣,但也有可能使用不同的方式。
現(xiàn)在,你可能有一個問題,我們是否可以創(chuàng)造我們自己的連接池機制?
?
我的建議是使用已經(jīng)存在的連接池機制,像C3P0,DBCP等。
總結(jié)
以上是生活随笔為你收集整理的Java 连接池的工作原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。