您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關c3p0數據庫連接池如何進行配置,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
c3p0的配置方式分為三種,分別是
1.setters一個個地設置各個配置項
2.類路徑下提供一個c3p0.properties文件
3.類路徑下提供一個c3p0-config.xml文件
1.setters一個個地設置各個配置項
這種方式最繁瑣,形式一般是這樣:
Properties props = new Properties(); InputStream in = ConnectionManager.class.getResourceAsStream("/c3p0.properties"); props.load(in); in.close(); ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass(props.getProperty("driverClass")); cpds.setJdbcUrl(props.getProperty("jdbcUrl")); cpds.setUser(props.getProperty("user")); cpds.setPassword(props.getProperty("password"));
因為繁瑣,所以很不適合采用,于是文檔提供了另外另種方式。
2. 類路徑下提供一個c3p0.properties文件
文件的命名必須是c3p0.properties,里面配置項的格式為:
c3p0.driverClass=com.mysql.jdbc.Driver c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc c3p0.user=root c3p0.password=java
上面只提供了最基本的配置項,其他配置項參照 文檔配置,記得是c3p0.后面加屬性名就是了,最后初始化數據源的方式就是這樣簡單:
private static ComboPooledDataSource ds = new ComboPooledDataSource(); public static Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { throw new RuntimeException(e); } }
3.類路徑下提供一個c3p0-config.xml文件
這種方式使用方式與第二種差不多,但是有更多的優點
(1).更直觀明顯,很類似hibernate和spring的配置
(2).可以為多個數據源服務,提供default-config和named-config兩種配置方式
下面是一個配置模板:
<c3p0-config> <default-config> <property name="user">root</property> <property name="password">java</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> </default-config> <named-config name="myApp"> <property name="user">root</property> <property name="password">java</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> </named-config> </c3p0-config>
如果要使用default-config則初始化數據源的方式與第二種一樣,如果要使用named-config里面配置初始化數據源,則只要使用一個帶參數的ComboPooledDataSource構造器就可以了
private static ComboPooledDataSource ds = new ComboPooledDataSource("myApp");
下面整理一下從文檔和網上學習到的c3p0配置的理解 (user,password,driverClass,jdbcUrl沒有說的必要)
1.基本配置項
acquireIncrement
default : 3
連接池在無空閑連接可用時一次性創建的新數據庫連接數
initialPoolSize
default : 3
連接池初始化時創建的連接數
maxPoolSize
default : 15
連接池中擁有的最大連接數,如果獲得新連接時會使連接總數超過這個值則不會再獲取新連接,而是等待
其他連接釋放,所以這個值有可能會設計地很大
maxIdleTime
default : 0 單位 s
連接的最大空閑時間,如果超過這個時間,某個數據庫連接還沒有被使用,則會斷開掉這個連接
如果為0,則永遠不會斷開連接
minPoolSize
default : 3
連接池保持的最小連接數,后面的maxIdleTimeExcessConnections跟這個配合使用來減輕連接池的負載
2.管理連接池的大小和連接的生存時間
maxConnectionAge
default : 0 單位 s
配置連接的生存時間,超過這個時間的連接將由連接池自動斷開丟棄掉。當然正在使用的連接不會馬上斷開,而是等待
它close再斷開。配置為0的時候則不會對連接的生存時間進行限制。
maxIdleTimeExcessConnections
default : 0 單位 s
這個配置主要是為了減輕連接池的負載,比如連接池中連接數因為某次數據訪問高峰導致創建了很多數據連接
但是后面的時間段需要的數據庫連接數很少,則此時連接池完全沒有必要維護那么多的連接,所以有必要將
斷開丟棄掉一些連接來減輕負載,必須小于maxIdleTime。配置不為0,則會將連接池中的連接數量保持到minPoolSize。
為0則不處理。
maxIdleTime也可以歸屬到這一類,前面已經寫出來了。
3.配置連接測試:因為連接池中的數據庫連接很有可能是維持數小時的連接,很有可能因為數據庫服務器的問題,網絡問題等導致實際連接已經無效,但是連接池里面的連接還是有效的,如果此時獲得連接肯定會發生異常,所以有必要通過測試連接來確認連接的有效性。
下面的前三項用來配置如何對連接進行測試,后三項配置對連接進行測試的時機。
automaticTestTable
default : null
用來配置測試連接的一種方式。配置一個表名,連接池根據這個表名創建一個空表,
并且用自己的測試sql語句在這個空表上測試數據庫連接
這個表只能由c3p0來使用,用戶不能操作,同時用戶配置的preferredTestQuery 將會被忽略。
preferredTestQuery
default : null
用來配置測試連接的另一種方式。與上面的automaticTestTable二者只能選一。
如果要用它測試連接,千萬不要設為null,否則測試過程會很耗時,同時要保證sql語句中的表在數據庫中一定存在。
connectionTesterClassName
default : com.mchange.v2.c3p0.impl.DefaultConnectionTester
連接池用來支持automaticTestTable和preferredTestQuery測試的類,必須是全類名,就像默認的那樣,
可以通過實現UnifiedConnectionTester接口或者繼承AbstractConnectionTester來定制自己的測試方法
idleConnectionTestPeriod
default : 0
用來配置測試空閑連接的間隔時間。測試方式還是上面的兩種之一,可以用來解決MySQL8小時斷開連接的問題。因為它
保證連接池會每隔一定時間對空閑連接進行一次測試,從而保證有效的空閑連接能每隔一定時間訪問一次數據庫,將于MySQL
8小時無會話的狀態打破。為0則不測試。
testConnectionOnCheckin
default : false
如果為true,則在close的時候測試連接的有效性。為了提高測試性能,可以與idleConnectionTestPeriod搭配使用,
配置preferredTestQuery或automaticTestTable也可以加快測試速度。
testConnectionOnCheckout
default : false
性能消耗大。如果為true,在每次getConnection的時候都會測試,為了提高性能,
可以與idleConnectionTestPeriod搭配使用,
配置preferredTestQuery或automaticTestTable也可以加快測試速度。
4.配置PreparedStatement緩存
maxStatements
default : 0
連接池為數據源緩存的PreparedStatement的總數。由于PreparedStatement屬于單個Connection,所以
這個數量應該根據應用中平均連接數乘以每個連接的平均PreparedStatement來計算。為0的時候不緩存,
同時maxStatementsPerConnection的配置無效。
maxStatementsPerConnection
default : 0
連接池為數據源單個Connection緩存的PreparedStatement數,這個配置比maxStatements更有意義,因為
它緩存的服務對象是單個數據連接,如果設置的好,肯定是可以提高性能的。為0的時候不緩存。
5.重連相關配置
acquireRetryAttempts
default : 30
連接池在獲得新連接失敗時重試的次數,如果小于等于0則無限重試直至連接獲得成功
acquireRetryDelay
default : 1000 單位ms
連接池在獲得新連接時的間隔時間
breakAfterAcquireFailure
default : false
如果為true,則當連接獲取失敗時自動關閉數據源,除非重新啟動應用程序。所以一般不用。
個人覺得上述三個沒有更改的必要,但可以將acquireRetryDelay配置地更短一些
6.定制管理Connection的生命周期
connectionCustomizerClassName
default : null
用來定制Connection的管理,比如在Connection acquire 的時候設定Connection的隔離級別,或者在
Connection丟棄的時候進行資源關閉,就可以通過繼承一個AbstractConnectionCustomizer來實現相關
方法,配置的時候使用全類名。有點類似監聽器的作用。
例如:
import java.sql.Connection; import com.mchange.v2.c3p0.AbstractConnectionCustomizer; public class ConnectionCustomizer extends AbstractConnectionCustomizer{ @Override public void onAcquire(Connection c, String parentDataSourceIdentityToken) throws Exception { System.out.println("acquire : " + c); } @Override public void onCheckIn(Connection c, String parentDataSourceIdentityToken) throws Exception { System.out.println("checkin : " + c); } @Override public void onCheckOut(Connection c, String parentDataSourceIdentityToken) throws Exception { System.out.println("checkout : " + c); } @Override public void onDestroy(Connection c, String parentDataSourceIdentityToken) throws Exception { System.out.println("destroy : " + c); } }
<property name="connectionCustomizerClassName">liuyun.zhuge.db.ConnectionCustomizer</property>
7.配置未提交的事務處理
autoCommitOnClose
default : false
連接池在回收數據庫連接時是否自動提交事務
如果為false,則會回滾未提交的事務
如果為true,則會自動提交事務
forceIgnoreUnresolvedTransactions
default : false
這個配置強烈不建議為true。
一般來說事務當然由自己關閉了,為什么要讓連接池來處理這種不細心問題呢?
8.配置debug和回收Connection 一般來說事務當然由自己關閉了,為什么要讓連接池來處理這種不細心問題呢?
unreturnedConnectionTimeout
default : 0 單位 s
為0的時候要求所有的Connection在應用程序中必須關閉。如果不為0,則強制在設定的時間到達后回收
Connection,所以必須小心設置,保證在回收之前所有數據庫操作都能夠完成。這種限制減少Connection未關閉
情況的不是很適用。為0不對connection進行回收,即使它并沒有關閉。
debugUnreturnedConnectionStackTraces
default : false
如果為true并且unreturnedConnectionTimeout設為大于0的值,當所有被getConnection出去的連接
unreturnedConnectionTimeout時間到的時候,就會打印出堆棧信息。只能在debug模式下適用,因為
打印堆棧信息會減慢getConnection的速度
同第七項一樣的,連接用完當然得close了,不要通過unreturnedConnectionTimeout讓連接池來回收未關閉的連接。
9.其他配置項:因為有些配置項幾乎沒有自己配置的必要,使用默認值就好,所以沒有再寫出來
checkoutTimeout
default : 0
配置當連接池所有連接用完時應用程序getConnection的等待時間。為0則無限等待直至有其他連接釋放
或者創建新的連接,不為0則當時間到的時候如果仍沒有獲得連接,則會拋出SQLException
三、示例:
示例采用第二種方式:
1.c3p0.properties:
#驅動 c3p0.driverClass=com.mysql.jdbc.Driver #地址 c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc #用戶名 c3p0.user=root #密碼 c3p0.password=lovejava #------------------------------- #連接池初始化時創建的連接數 c3p0.initialPoolSize=3 #連接池保持的最小連接數 c3p0.minPoolSize=3 #連接池在無空閑連接可用時一次性創建的新數據庫連接數,default:3 c3p0.acquireIncrement=3 #連接池中擁有的最大連接數,如果獲得新連接時會使連接總數超過這個值則不會再獲取新連接,而是等待其他連接釋放,所以這個值有可能會設計地很大,default : 15 c3p0.maxPoolSize=15 #連接的最大空閑時間,如果超過這個時間,某個數據庫連接還沒有被使用,則會斷開掉這個連接,單位秒 c3p0.maxIdleTime=100 #連接池在獲得新連接失敗時重試的次數,如果小于等于0則無限重試直至連接獲得成功 c3p0.acquireRetryAttempts=30 #連接池在獲得新連接時的間隔時間 c3p0.acquireRetryDelay=1000
2.ConnectionPool
package com.study.pool; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class ConnectionPool { private DataSource ds; private static ConnectionPool pool; private ConnectionPool(){ ds = new ComboPooledDataSource(); } public static final ConnectionPool getInstance(){ if(pool==null){ try{ pool = new ConnectionPool(); }catch (Exception e) { e.printStackTrace(); } } return pool; } public synchronized final Connection getConnection() { try { return ds.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } }
3.PoolThread
package com.study.pool; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class PoolThread extends Thread { @Override public void run(){ ConnectionPool pool = ConnectionPool.getInstance(); Connection con = null; PreparedStatement stmt= null; ResultSet rs = null; try{ con = pool.getConnection(); stmt = con.prepareStatement("select sysdate as nowtime from dual"); rs = stmt.executeQuery(); while(rs.next()){ System.out.println(Thread.currentThread().getId()+"---------------開始"+rs.getString("nowtime")); } } catch (Exception e) { e.printStackTrace(); }finally{ try { rs.close(); stmt.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getId()+"--------結束"); } }
4.PoolMain
package com.study.pool; public class PoolMain { /** * 數據源緩沖池 實例練習 */ public static void main(String[] args) { System.out.println("緩沖池模擬開始"); PoolThread[] threads = new PoolThread[50]; for(int i=0;i<threads.length;i++){ threads[i] = new PoolThread(); } for(int i=0;i<threads.length;i++){ threads[i].start(); } } }
關于c3p0數據庫連接池如何進行配置就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。