JDBC連接池C3P0
連接池
1)傳統方式找DriverManager要連接。數目是有限的。
2)傳統方式的close()。並沒有將Connection重用。僅僅是切斷應用程序和數據庫的橋梁,即無發送到SQL命令到數據庫端運行
3)項目中,對於Connection不說,不會直接使用DriverManager取得,而使用連接池方式。
4)DBCP和C3P0,都是Java開源的。都必須直接或間接實現javax.sql.DataSource接口
5)DBCP連接池須要dbcp.properties文件。同一時候需增加3個相應的jar包
*6)C3P0連接池須要在/WEB-INF/classes/文件夾下存放c3p0-config.xml文件,該類ComboPooledDataSource在創建時
會自己主動在指定的文件夾下找xml文件,並載入默認設置
7)重構JdbcUtil類
DBCP連接池
l DBCP 是 Apache 軟件基金組織下的開源連接池實現,使用DBCP數據源,應用程序應在系統中添加例如以下兩個 jar 文件:
? commons-dbcp.jar:連接池的實現
? commons-pool.jar: 連接池實現的依賴類
? commons-collections.jar :連接池實現的集合類
l Tomcat 的連接池正是採用該連接池來實現的。
#dbcp.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydb2
username=root
password=root
關鍵代碼
static{
InputStreamin = JdbcUtil.class.getClassLoader().
getResourceAsStream("dbcp.properties");
Propertiesprop = new Properties();
prop.load(in);
BasicDataSourceFactoryfactory = new BasicDataSourceFactory();
dataSource = factory.createDataSource(prop);
}
實例代碼:
//測試連接池DBCP的使用方法
publicclass Demo2 {
publicstaticvoid main(String[] args) throws Exception {
long begin = System.currentTimeMillis();
//載入屬性文件
InputStream is = Demo2.class.getClassLoader().getResourceAsStream("dbcp.properties");
Properties props = new Properties();
props.load(is);
//創建DBCP連接池工廠
BasicDataSourceFactory factory = new BasicDataSourceFactory();
//創建數據源,即連接池
DataSource ds = factory.createDataSource(props);
for(int i=1;i<=50000;i++){
//從連接池中取得一個空暇的連接對象
Connection conn = ds.getConnection();
if(conn!=null){
System.out.println(i+":取得連接");
}
//將連接對象還回給連接池
conn.close();
}
long end = System.currentTimeMillis();
System.out.println("共用" + (end-begin)/1000+"秒");
}
}
c3p0:
配置文件:
<?
xml version="1.0"encoding="UTF-8"?>
<!-- 文件名稱不能亂改,須用默認的c3o0-config.xml -->
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb2</property>
</default-config>
</c3p0-config>
/推薦使用c3p0連接池
//測試連接池C3P0的使用方法
publicclass Demo3 {
publicstaticvoid main(String[] args) throws Exception {
long begin = System.currentTimeMillis();
//創建C3P0連接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
for(int i=1;i<=100000;i++){
Connection conn = dataSource.getConnection();
if(conn!=null){
System.out.println(i+":取得連接");
conn.close();
}
}
long end = System.currentTimeMillis();
System.out.println("共用" + (end-begin)/1000+"秒");
}
}
JdbcUtil工具類,封裝從c3p0的連接池獲取連接:
//JDBC工具類:關閉流和取得連接
publicfinalclass JdbcUtil3 {
//數據源
privatestatic ComboPooledDataSource dataSource;
static{//靜態塊。讀取c3p0默認配置文件
dataSource = new ComboPooledDataSource();
}
//取得連接
publicstatic Connection getMySqlConnection() throws SQLException{
return dataSource.getConnection();
}
//關閉連接
publicstaticvoid close(Connection conn) throws SQLException{
if(conn!=null){
conn.close();
}
}
}
C3P0連接池詳細參數說明例如以下:
c3p0-config>
<default-config>
<!--當連接池中的連接耗盡的時候c3p0一次同一時候獲取的連接數。Default:3
-->
<propertyname="acquireIncrement">3</property>
<!--定義在從數據庫獲取新連接失敗後反復嘗試的次數。Default: 30 -->
<property name="acquireRetryAttempts">30</property>
<!--兩次連接中間隔時間,單位毫秒。Default:1000 -->
<property name="acquireRetryDelay">1000</property>
<!--連接關閉時默認將全部未提交的操作回滾。Default:false -->
<propertyname="autoCommitOnClose">false</property>
<!--c3p0將建一張名為Test的空表,並使用其自帶的查詢語句進行測試。
假設定義了這個參數那麽
屬性preferredTestQuery將被忽略。
你不能在這張Test表上進行不論什麽操作,它將僅僅供c3p0測試
使用。Default:null-->
<propertyname="automaticTestTable">Test</property>
<!--獲取連接失敗將會引起全部等待連接池來獲取連接的線程拋出異常。可是數據源仍有效
保留。並在下次調用getConnection()的時候繼續嘗試獲取連接。
假設設為true,那麽在嘗試
獲取連接失敗後該數據源將申明已斷開並永久關閉。Default: false-->
<property name="breakAfterAcquireFailure">false</property>
<!--當連接池用完時client調用getConnection()後等待獲取新連接的時間,超時後將拋出
SQLException,如設為0則無限期等待。單位毫秒。
Default: 0 -->
<property name="checkoutTimeout">100</property>
<!--通過實現ConnectionTester或QueryConnectionTester的類來測試連接。類名需制定全路徑。
Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->
<propertyname="connectionTesterClassName"></property>
<!--指定c3p0 libraries的路徑,假設(通常都是這樣)在本地就可以獲得那麽無需設置。默認null就可以
Default: null-->
<propertyname="factoryClassLocation">null</property>
<!--Stronglydisrecommended. Setting this to true may lead to subtle and bizarre bugs.
(文檔原文)作者強烈建議不使用的一個屬性-->
<propertyname="forceIgnoreUnresolvedTransactions">false</property>
<!--每60秒檢查全部連接池中的空暇連接。Default:
0 -->
<property name="idleConnectionTestPeriod">60</property>
<!--初始化時獲取三個連接,取值應在minPoolSize與maxPoolSize之間。Default:
3 -->
<property name="initialPoolSize">3</property>
<!--最大空暇時間,60秒內未使用則連接被丟棄。
若為0則永不丟棄。
Default:
0 -->
<propertyname="maxIdleTime">60</property>
<!--連接池中保留的最大連接數。Default:15 -->
<property name="maxPoolSize">15</property>
<!--JDBC的標準參數。用以控制數據源內載入的PreparedStatements數量。但因為預緩存的statements
屬於單個connection而不是整個連接池。
所以設置這個參數須要考慮到多方面的因素。
假設maxStatements與maxStatementsPerConnection均為0。則緩存被關閉。Default:
0-->
<property name="maxStatements">100</property>
<!--maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數。Default:
0 -->
<propertyname="maxStatementsPerConnection"></property>
<!--c3p0是異步操作的,緩慢的JDBC操作通過幫助進程完畢。擴展這些操作能夠有效的提升性能
通過多線程實現多個操作同一時候被運行。
Default:3-->
<property name="numHelperThreads">3</property>
<!--當用戶調用getConnection()時使root用戶成為去獲取連接的用戶。
主要用於連接池連接非c3p0
的數據源時。Default:null-->
<propertyname="overrideDefaultUser">root</property>
<!--與overrideDefaultUser參數相應使用的一個參數。Default:null-->
<property name="overrideDefaultPassword">password</property>
<!--password。Default: null-->
<property name="password"></property>
<!--定義全部連接測試都運行的測試語句。在使用連接測試的情況下這個一顯著提高測試速度。
註意:
測試的表必須在初始數據源的時候就存在。Default:null-->
<propertyname="preferredTestQuery">select id from test whereid=1</property>
<!--用戶改動系統配置參數運行前最多等待300秒。
Default:
300 -->
<property name="propertyCycle">300</property>
<!--因性能消耗大請僅僅在須要的時候使用它。假設設為true那麽在每一個connection提交的
時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable
等方法來提升連接測試的性能。
Default:false -->
<propertyname="testConnectionOnCheckout">false</property>
<!--假設設為true那麽在取得連接的同一時候將校驗連接的有效性。
Default:false
-->
<propertyname="testConnectionOnCheckin">true</property>
<!--username。Default: null-->
<propertyname="user">root</property>
<!--早期的c3p0版本號對JDBC接口採用動態反射代理。在早期版本號用途廣泛的情況下這個參數
同意用戶恢復到動態反射代理以解決不穩定的故障。
最新的非反射代理更快而且已經開始
廣泛的被使用,所以這個參數未必實用。如今原先的動態反射與新的非反射代理同一時候受到
支持,但今後可能的版本號可能不支持動態反射代理。Default: false-->
<propertyname="usesTraditionalReflectiveProxies">false</property>
<property name="automaticTestTable">con_test</property>
<propertyname="checkoutTimeout">30000</property>
<propertyname="idleConnectionTestPeriod">30</property>
<propertyname="initialPoolSize">10</property>
<propertyname="maxIdleTime">30</property>
<propertyname="maxPoolSize">25</property>
<propertyname="minPoolSize">10</property>
<propertyname="maxStatements">0</property>
<user-overrides user="swaldman">
</user-overrides>
</default-config>
<named-config name="dumbTestConfig">
<propertyname="maxStatements">200</property>
<user-overrides user="poop">
<propertyname="maxStatements">300</property>
</user-overrides>
</named-config>
</c3p0-config>
JDBC連接池C3P0