溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

c3p0數(shù)據(jù)庫(kù)連接池如何進(jìn)行配置

發(fā)布時(shí)間:2020-12-01 16:31:48 來(lái)源:億速云 閱讀:149 作者:Leah 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)c3p0數(shù)據(jù)庫(kù)連接池如何進(jìn)行配置,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

c3p0的配置方式分為三種,分別是

1.setters一個(gè)個(gè)地設(shè)置各個(gè)配置項(xiàng)
2.類路徑下提供一個(gè)c3p0.properties文件
3.類路徑下提供一個(gè)c3p0-config.xml文件

1.setters一個(gè)個(gè)地設(shè)置各個(gè)配置項(xiàng)

這種方式最繁瑣,形式一般是這樣:

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"));

因?yàn)榉爆崳院懿贿m合采用,于是文檔提供了另外另種方式。

2. 類路徑下提供一個(gè)c3p0.properties文件

文件的命名必須是c3p0.properties,里面配置項(xiàng)的格式為:

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc
c3p0.user=root
c3p0.password=java

上面只提供了最基本的配置項(xiàng),其他配置項(xiàng)參照 文檔配置,記得是c3p0.后面加屬性名就是了,最后初始化數(shù)據(jù)源的方式就是這樣簡(jiǎn)單:

private static ComboPooledDataSource ds = new ComboPooledDataSource();

public static Connection getConnection() {

 try {
 return ds.getConnection();
 } catch (SQLException e) {
 throw new RuntimeException(e);
 }

}

3.類路徑下提供一個(gè)c3p0-config.xml文件

這種方式使用方式與第二種差不多,但是有更多的優(yōu)點(diǎn)
(1).更直觀明顯,很類似hibernate和spring的配置
(2).可以為多個(gè)數(shù)據(jù)源服務(wù),提供default-config和named-config兩種配置方式
下面是一個(gè)配置模板:

<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則初始化數(shù)據(jù)源的方式與第二種一樣,如果要使用named-config里面配置初始化數(shù)據(jù)源,則只要使用一個(gè)帶參數(shù)的ComboPooledDataSource構(gòu)造器就可以了

private static ComboPooledDataSource ds = new ComboPooledDataSource("myApp");
下面整理一下從文檔和網(wǎng)上學(xué)習(xí)到的c3p0配置的理解 (user,password,driverClass,jdbcUrl沒(méi)有說(shuō)的必要)

1.基本配置項(xiàng)

acquireIncrement

default : 3

連接池在無(wú)空閑連接可用時(shí)一次性創(chuàng)建的新數(shù)據(jù)庫(kù)連接數(shù)

initialPoolSize

default : 3

連接池初始化時(shí)創(chuàng)建的連接數(shù)

maxPoolSize

default : 15

連接池中擁有的最大連接數(shù),如果獲得新連接時(shí)會(huì)使連接總數(shù)超過(guò)這個(gè)值則不會(huì)再獲取新連接,而是等待

其他連接釋放,所以這個(gè)值有可能會(huì)設(shè)計(jì)地很大

maxIdleTime

default : 0 單位 s
連接的最大空閑時(shí)間,如果超過(guò)這個(gè)時(shí)間,某個(gè)數(shù)據(jù)庫(kù)連接還沒(méi)有被使用,則會(huì)斷開掉這個(gè)連接
如果為0,則永遠(yuǎn)不會(huì)斷開連接

minPoolSize
default : 3
連接池保持的最小連接數(shù),后面的maxIdleTimeExcessConnections跟這個(gè)配合使用來(lái)減輕連接池的負(fù)載

2.管理連接池的大小和連接的生存時(shí)間

maxConnectionAge

default : 0 單位 s

配置連接的生存時(shí)間,超過(guò)這個(gè)時(shí)間的連接將由連接池自動(dòng)斷開丟棄掉。當(dāng)然正在使用的連接不會(huì)馬上斷開,而是等待

它c(diǎn)lose再斷開。配置為0的時(shí)候則不會(huì)對(duì)連接的生存時(shí)間進(jìn)行限制。

maxIdleTimeExcessConnections

default : 0 單位 s

這個(gè)配置主要是為了減輕連接池的負(fù)載,比如連接池中連接數(shù)因?yàn)槟炒螖?shù)據(jù)訪問(wèn)高峰導(dǎo)致創(chuàng)建了很多數(shù)據(jù)連接

但是后面的時(shí)間段需要的數(shù)據(jù)庫(kù)連接數(shù)很少,則此時(shí)連接池完全沒(méi)有必要維護(hù)那么多的連接,所以有必要將

斷開丟棄掉一些連接來(lái)減輕負(fù)載,必須小于maxIdleTime。配置不為0,則會(huì)將連接池中的連接數(shù)量保持到minPoolSize。

為0則不處理。

maxIdleTime也可以歸屬到這一類,前面已經(jīng)寫出來(lái)了。

3.配置連接測(cè)試:因?yàn)檫B接池中的數(shù)據(jù)庫(kù)連接很有可能是維持?jǐn)?shù)小時(shí)的連接,很有可能因?yàn)閿?shù)據(jù)庫(kù)服務(wù)器的問(wèn)題,網(wǎng)絡(luò)問(wèn)題等導(dǎo)致實(shí)際連接已經(jīng)無(wú)效,但是連接池里面的連接還是有效的,如果此時(shí)獲得連接肯定會(huì)發(fā)生異常,所以有必要通過(guò)測(cè)試連接來(lái)確認(rèn)連接的有效性。
下面的前三項(xiàng)用來(lái)配置如何對(duì)連接進(jìn)行測(cè)試,后三項(xiàng)配置對(duì)連接進(jìn)行測(cè)試的時(shí)機(jī)。

automaticTestTable

default : null

用來(lái)配置測(cè)試連接的一種方式。配置一個(gè)表名,連接池根據(jù)這個(gè)表名創(chuàng)建一個(gè)空表,

并且用自己的測(cè)試sql語(yǔ)句在這個(gè)空表上測(cè)試數(shù)據(jù)庫(kù)連接

這個(gè)表只能由c3p0來(lái)使用,用戶不能操作,同時(shí)用戶配置的preferredTestQuery 將會(huì)被忽略。

preferredTestQuery

default : null

用來(lái)配置測(cè)試連接的另一種方式。與上面的automaticTestTable二者只能選一。

如果要用它測(cè)試連接,千萬(wàn)不要設(shè)為null,否則測(cè)試過(guò)程會(huì)很耗時(shí),同時(shí)要保證sql語(yǔ)句中的表在數(shù)據(jù)庫(kù)中一定存在。

connectionTesterClassName

default :  com.mchange.v2.c3p0.impl.DefaultConnectionTester

連接池用來(lái)支持automaticTestTable和preferredTestQuery測(cè)試的類,必須是全類名,就像默認(rèn)的那樣,

可以通過(guò)實(shí)現(xiàn)UnifiedConnectionTester接口或者繼承AbstractConnectionTester來(lái)定制自己的測(cè)試方法

idleConnectionTestPeriod

default : 0

用來(lái)配置測(cè)試空閑連接的間隔時(shí)間。測(cè)試方式還是上面的兩種之一,可以用來(lái)解決MySQL8小時(shí)斷開連接的問(wèn)題。因?yàn)樗?/p>

保證連接池會(huì)每隔一定時(shí)間對(duì)空閑連接進(jìn)行一次測(cè)試,從而保證有效的空閑連接能每隔一定時(shí)間訪問(wèn)一次數(shù)據(jù)庫(kù),將于MySQL

8小時(shí)無(wú)會(huì)話的狀態(tài)打破。為0則不測(cè)試。

testConnectionOnCheckin

default : false

如果為true,則在close的時(shí)候測(cè)試連接的有效性。為了提高測(cè)試性能,可以與idleConnectionTestPeriod搭配使用,

配置preferredTestQuery或automaticTestTable也可以加快測(cè)試速度。

testConnectionOnCheckout

default : false
性能消耗大。如果為true,在每次getConnection的時(shí)候都會(huì)測(cè)試,為了提高性能,

可以與idleConnectionTestPeriod搭配使用,

配置preferredTestQuery或automaticTestTable也可以加快測(cè)試速度。

4.配置PreparedStatement緩存

maxStatements
default : 0
連接池為數(shù)據(jù)源緩存的PreparedStatement的總數(shù)。由于PreparedStatement屬于單個(gè)Connection,所以
這個(gè)數(shù)量應(yīng)該根據(jù)應(yīng)用中平均連接數(shù)乘以每個(gè)連接的平均PreparedStatement來(lái)計(jì)算。為0的時(shí)候不緩存,
同時(shí)maxStatementsPerConnection的配置無(wú)效。

maxStatementsPerConnection
default : 0
連接池為數(shù)據(jù)源單個(gè)Connection緩存的PreparedStatement數(shù),這個(gè)配置比maxStatements更有意義,因?yàn)?br/>它緩存的服務(wù)對(duì)象是單個(gè)數(shù)據(jù)連接,如果設(shè)置的好,肯定是可以提高性能的。為0的時(shí)候不緩存。

5.重連相關(guān)配置

acquireRetryAttempts

default : 30

連接池在獲得新連接失敗時(shí)重試的次數(shù),如果小于等于0則無(wú)限重試直至連接獲得成功

acquireRetryDelay

default : 1000 單位ms

連接池在獲得新連接時(shí)的間隔時(shí)間

breakAfterAcquireFailure
default : false

如果為true,則當(dāng)連接獲取失敗時(shí)自動(dòng)關(guān)閉數(shù)據(jù)源,除非重新啟動(dòng)應(yīng)用程序。所以一般不用。
個(gè)人覺(jué)得上述三個(gè)沒(méi)有更改的必要,但可以將acquireRetryDelay配置地更短一些

6.定制管理Connection的生命周期

connectionCustomizerClassName
default : null
用來(lái)定制Connection的管理,比如在Connection acquire 的時(shí)候設(shè)定Connection的隔離級(jí)別,或者在
Connection丟棄的時(shí)候進(jìn)行資源關(guān)閉,就可以通過(guò)繼承一個(gè)AbstractConnectionCustomizer來(lái)實(shí)現(xiàn)相關(guān)

方法,配置的時(shí)候使用全類名。有點(diǎn)類似監(jiān)聽器的作用。
例如:

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.配置未提交的事務(wù)處理

autoCommitOnClose

default : false

連接池在回收數(shù)據(jù)庫(kù)連接時(shí)是否自動(dòng)提交事務(wù)

如果為false,則會(huì)回滾未提交的事務(wù)

如果為true,則會(huì)自動(dòng)提交事務(wù)

forceIgnoreUnresolvedTransactions

default : false

這個(gè)配置強(qiáng)烈不建議為true。
一般來(lái)說(shuō)事務(wù)當(dāng)然由自己關(guān)閉了,為什么要讓連接池來(lái)處理這種不細(xì)心問(wèn)題呢?

8.配置debug和回收Connection 一般來(lái)說(shuō)事務(wù)當(dāng)然由自己關(guān)閉了,為什么要讓連接池來(lái)處理這種不細(xì)心問(wèn)題呢?

unreturnedConnectionTimeout
default : 0 單位 s
為0的時(shí)候要求所有的Connection在應(yīng)用程序中必須關(guān)閉。如果不為0,則強(qiáng)制在設(shè)定的時(shí)間到達(dá)后回收
Connection,所以必須小心設(shè)置,保證在回收之前所有數(shù)據(jù)庫(kù)操作都能夠完成。這種限制減少Connection未關(guān)閉
情況的不是很適用。為0不對(duì)connection進(jìn)行回收,即使它并沒(méi)有關(guān)閉。

debugUnreturnedConnectionStackTraces
default : false
如果為true并且unreturnedConnectionTimeout設(shè)為大于0的值,當(dāng)所有被getConnection出去的連接
unreturnedConnectionTimeout時(shí)間到的時(shí)候,就會(huì)打印出堆棧信息。只能在debug模式下適用,因?yàn)?br/>打印堆棧信息會(huì)減慢getConnection的速度
同第七項(xiàng)一樣的,連接用完當(dāng)然得close了,不要通過(guò)unreturnedConnectionTimeout讓連接池來(lái)回收未關(guān)閉的連接。

9.其他配置項(xiàng):因?yàn)橛行┡渲庙?xiàng)幾乎沒(méi)有自己配置的必要,使用默認(rèn)值就好,所以沒(méi)有再寫出來(lái)

checkoutTimeout
default : 0
配置當(dāng)連接池所有連接用完時(shí)應(yīng)用程序getConnection的等待時(shí)間。為0則無(wú)限等待直至有其他連接釋放
或者創(chuàng)建新的連接,不為0則當(dāng)時(shí)間到的時(shí)候如果仍沒(méi)有獲得連接,則會(huì)拋出SQLException

三、示例:

示例采用第二種方式:

1.c3p0.properties:

#驅(qū)動(dòng) 
c3p0.driverClass=com.mysql.jdbc.Driver 
#地址 
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/jdbc 
#用戶名 
c3p0.user=root 
#密碼 
c3p0.password=lovejava 
#------------------------------- 
#連接池初始化時(shí)創(chuàng)建的連接數(shù) 
c3p0.initialPoolSize=3 
#連接池保持的最小連接數(shù) 
c3p0.minPoolSize=3 
#連接池在無(wú)空閑連接可用時(shí)一次性創(chuàng)建的新數(shù)據(jù)庫(kù)連接數(shù),default:3 
c3p0.acquireIncrement=3 
#連接池中擁有的最大連接數(shù),如果獲得新連接時(shí)會(huì)使連接總數(shù)超過(guò)這個(gè)值則不會(huì)再獲取新連接,而是等待其他連接釋放,所以這個(gè)值有可能會(huì)設(shè)計(jì)地很大,default : 15 
c3p0.maxPoolSize=15 
#連接的最大空閑時(shí)間,如果超過(guò)這個(gè)時(shí)間,某個(gè)數(shù)據(jù)庫(kù)連接還沒(méi)有被使用,則會(huì)斷開掉這個(gè)連接,單位秒 
c3p0.maxIdleTime=100 
#連接池在獲得新連接失敗時(shí)重試的次數(shù),如果小于等于0則無(wú)限重試直至連接獲得成功 
c3p0.acquireRetryAttempts=30 
#連接池在獲得新連接時(shí)的間隔時(shí)間 
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()+"--------結(jié)束"); 
 } 
}

4.PoolMain

package com.study.pool; 
 
public class PoolMain { 
 
 /** 
 * 數(shù)據(jù)源緩沖池 實(shí)例練習(xí) 
 */ 
 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(); 
 } 
 } 
 
}

關(guān)于c3p0數(shù)據(jù)庫(kù)連接池如何進(jìn)行配置就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI