1.c3p0簡(jiǎn)介
c3p0被設(shè)計(jì)成易于使用。只需要在項(xiàng)目中導(dǎo)入相關(guān)jar包即可,導(dǎo)入相關(guān)包時(shí),需要注意,包的版本的及依賴包的版本
<dependencies>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
即可進(jìn)行簡(jiǎn)單的數(shù)據(jù)庫(kù)操作
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("dbuser");
cpds.setPassword("dbpassword");
如果需要打開(kāi)PreparedStatement池,需要設(shè)置maxStatements、 maxStatementsPerConnection ,它們的默認(rèn)值都是0.
cpds.setMaxStatements( 180 );
使用完成后,清理
cpds.close();就是這樣,剩下的就是細(xì)節(jié)了。
2.c3p0使用
獲取c3p0池支持的DataSource有三種方法:
- 直接實(shí)例化和配置一個(gè)ComboPooledDataSource實(shí)例。
- 使用DataSources工廠類
- 通過(guò)直接實(shí)例化PoolBackedDataSource并設(shè)置其ConectionPoolDataSource來(lái)“構(gòu)建您自己的”池支持的DataSource
大多數(shù)用戶可能會(huì)發(fā)現(xiàn)實(shí)例化ComboPooledDataSource是最方便的方法。 實(shí)例化后,c3p0 DataSources幾乎可以綁定到任何符合JNDI的名稱服務(wù)。
實(shí)例化和配置一個(gè)ComboPooledDataSource
ds = new ComboPooledDataSource();
// ds.setDriverClass(env.getProperty("jdbc.driver"));
// ds.setJdbcUrl(url);
// ds.setUser(username);
// ds.setPassword(password);
// ds.setMaxPoolSize(200);
// ds.setMinPoolSize(10);
// ds.setInitialPoolSize(50);
// ds.setMaxStatements(180);
3. c3p0 PooledDataSources的清理工作
DataSources.destroy( ds_pooled );
或者,c3p0的PooledDataSource接口包含一個(gè)close()方法,當(dāng)您知道已完成DataSource時(shí)可以調(diào)用該方法
4.c3p0配置
雖然c3p0不需要很多配置,但它是非??烧{(diào)整的。有幾種方法可以修改c3p0屬性:您可以直接更改代碼中與特定DataSource關(guān)聯(lián)的屬性值,也可以從外部配置c3p0
- 通過(guò)一個(gè)簡(jiǎn)單的Java屬性文件
- 通過(guò)XML配置文件
數(shù)據(jù)源通常在使用之前進(jìn)行配置,或者在構(gòu)建過(guò)程中進(jìn)行配置,或者在構(gòu)建之后立即進(jìn)行配置。然而,c3p0確實(shí)支持中途修改屬性.如果通過(guò)實(shí)例化ComboPooledDataSource獲取DataSource,則在嘗試調(diào)用getConnection()之前,通過(guò)調(diào)用該類提供的適當(dāng)setter方法來(lái)配置它。 請(qǐng)參閱上面的示例。如果你通過(guò)使用com.mchange.v2.c3g0.DataSources類中的工廠方法獲取DataSources, 并且不想使用默認(rèn)的配置,你可以提供一個(gè)帶有屬性鍵值對(duì)的Map.
5.基本的池配置
- acquireIncrement
- initialPoolSize
- maxPoolSize
- maxIdleTime
- minPoolSize
nitialPoolSize,minPoolSize,maxPoolSize定義將池的Connections數(shù)。 請(qǐng)確保minPoolSize <= maxPoolSize。 將忽略initialPoolSize的不合理值,而使用minPoolSize。在minPoolSize和maxPoolSize之間的范圍內(nèi),池中的連接數(shù)根據(jù)使用模式而有所不同.每當(dāng)用戶請(qǐng)求連接,沒(méi)有可用的連接,并且池中的管理連接數(shù)尚未達(dá)到maxPoolSize時(shí),連接數(shù)就會(huì)增加.由于連接獲取速度非常慢,因此更早的增加連接數(shù)量幾乎總是有用的,而不是強(qiáng)迫每個(gè)客戶端等待新連接在負(fù)載增加時(shí)引發(fā)單個(gè)獲取。acquireIncrement確定當(dāng)池用完連接時(shí)c3p0池將嘗試獲取的連接數(shù)。無(wú)論 acquireIncrement設(shè)置多少,池永遠(yuǎn)都不會(huì)允許超過(guò) maxPoolSize。
6.管理池大小和連接時(shí)間
不同的應(yīng)用程序在性能,占用空間和可靠性之間的權(quán)衡方面有不同的需求。C3P0提供了多種選項(xiàng),用于控制在負(fù)載下變大的池恢復(fù)到minPoolSize的速度,以及是否應(yīng)主動(dòng)替換池中的“舊”連接以保持其可靠性。
- maxConnectionAge
- maxIdleTime
- maxIdleTimeExcessConnections
默認(rèn)情況下,池永遠(yuǎn)不會(huì)到期連接。 如果您希望Connections隨著時(shí)間的推移而過(guò)期,以保持“新鮮度”,設(shè)置maxIdleTime and/or maxConnectionAge. maxIdleTime定義在從池中刪除連接之前,應(yīng)該允許連接閑置多長(zhǎng)時(shí)間。maxConnectionAge 強(qiáng)制池剔除過(guò)去從數(shù)據(jù)庫(kù)中獲取的超過(guò)設(shè)置秒數(shù)的任何連接。maxIdleTimeExcessConnections 是關(guān)于在池未加載時(shí)最小化c3p0池所持有的連接數(shù)。默認(rèn)情況下,c3p0池在負(fù)載下會(huì)增長(zhǎng),但只有在連接未通過(guò)連接測(cè)試或通過(guò)上述參數(shù)過(guò)期時(shí)才會(huì)收縮。一些用戶希望他們的池在使用高峰后快速釋放不必要的連接。關(guān)于所有這些超時(shí)參數(shù)的一些一般建議:慢下來(lái)! 連接池的要點(diǎn)是承擔(dān)僅獲取一次Connection的成本,然后多次重復(fù)使用Connection。 大多數(shù)數(shù)據(jù)庫(kù)支持一次保持打開(kāi)數(shù)小時(shí)的連接。 每隔幾秒鐘或幾分鐘就無(wú)需流失所有連接。 將maxConnectionAge或maxIdleTime設(shè)置為1800(30分鐘)非常激進(jìn)。 對(duì)于大多數(shù)數(shù)據(jù)庫(kù),幾個(gè)小時(shí)可能更合適。 您可以通過(guò)測(cè)試來(lái)確保Connections的可靠性,而不是通過(guò)拋棄它們來(lái)確保它們的可靠性。 (請(qǐng)參閱配置連接測(cè)試。)通常應(yīng)設(shè)置為幾分鐘或更短時(shí)間的這些參數(shù)中唯一一個(gè)是maxIdleTimeExcessConnections。
7.hibernate c3p0
導(dǎo)入相關(guān)包,注意包的版本問(wèn)題,否則無(wú)法支持相關(guān)功能:
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.3.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.3.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.logging/jboss-logging -->
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.2.Final</version>
</dependency>
其相關(guān)依賴包都要相應(yīng)導(dǎo)入,導(dǎo)入時(shí)需注意包的版本依賴

相關(guān)包導(dǎo)入后,即可在項(xiàng)目中,進(jìn)行相關(guān)配置,來(lái)使用數(shù)據(jù)庫(kù)連接池的功能了
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<property name="format_sql">false</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<property name="c3p0.min_size">5</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.timeout">120</property>
<property name="c3p0.idle_test_period">3000</property>
</session-factory>
</hibernate-configuration>
mysql數(shù)據(jù)庫(kù)
hibernate.cfg.xml配置
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/dbname?useSSL=false</property>
<property name="connection.characterEncoding">utf-8 </property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
在dao層進(jìn)行查詢操作時(shí),使用
Object result = query.uniqueResult();要注意,因?yàn)樵摲椒ㄔ诓樵優(yōu)榭諘r(shí),返回的是null,不能進(jìn)行諸如
(Long)null此類的強(qiáng)制類型轉(zhuǎn)換,所以需要另外處理
oracle數(shù)據(jù)庫(kù)
hibernate.cfg.xml配置
<property name="dialect">org.hibernate.dialect.Oracle9iDialect</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:sid</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
c3p0配置
使用c3p0數(shù)據(jù)庫(kù)連接池配置
<!--連接池中保留的最小連接數(shù)。-->
<property name="c3p0.min_size">5</property>
<!--連接池中保留的最大連接數(shù)。Default: 15 -->
<property name="c3p0.max_size">30</property>
<!-- 獲得連接的超時(shí)時(shí)間,如果超過(guò)這個(gè)時(shí)間,會(huì)拋出異常,單位毫秒 -->
<property name="c3p0.timeout">120</property>
<!-- 每隔3000秒檢查連接池里的空閑連接 ,單位是秒-->
<property name="c3p0.idle_test_period">3000</property>
<!-- 當(dāng)連接池里面的連接用完的時(shí)候,C3P0一下獲取的新的連接數(shù) -->
<property name="c3p0.acquire_increment">2</property>
<!-- 每次都驗(yàn)證連接是否可用 -->
<property name="c3p0.validate">true</property>
c3p0驗(yàn)證是否配置生效的方法:
1.日志會(huì)打印出相關(guān),Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@6f43311e [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@8e2adb8b [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hgeky5a42eya661mluequ|3d1848cc, idleConnectionTestPeriod -> 3000, initialPoolSize -> 5, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 120, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 30, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@a32d3f56 [ description -> null, driverClass -> null, factoryClassLocation -> null, identityToken -> 1hgeky5a42eya661mluequ|336f1079, jdbcUrl -> jdbc:oracle:thin:@127.0.0.1:1521:orcl, properties -> {user=******, password=******} ], preferredTestQuery -> null, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, identityToken -> 1hgeky5a42eya661mluequ|2ea6e30c, numHelperThreads -> 3 ]
2.mysql數(shù)據(jù)庫(kù)可以查看
show processlist;
+-----+------+-----------------+----------------+---------+------+----------+------------------+
| 413 | root | localhost:60627 | localhost_mayi | Sleep | 49 | | NULL |
| 414 | root | localhost:60628 | NULL | Sleep | 56 | | NULL |
| 457 | root | localhost | NULL | Query | 0 | starting | show processlist |
| 463 | root | localhost:62823 | localhost_mayi | Sleep | 12 | | NULL |
| 464 | root | localhost:62822 | localhost_mayi | Sleep | 12 | | NULL |
| 465 | root | localhost:62824 | localhost_mayi | Sleep | 1 | | NULL |
| 466 | root | localhost:62825 | localhost_mayi | Sleep | 0 | | NULL |
| 467 | root | localhost:62826 | localhost_mayi | Sleep | 12 | | NULL |
+-----+------+-----------------+----------------+---------+------+----------+------------------+
8 rows in set (0.00 sec)
注 :無(wú)論使用何種數(shù)據(jù)庫(kù)存儲(chǔ),都把相關(guān)驅(qū)動(dòng)提前加入到pom文件中,后續(xù)僅僅調(diào)整配置文件即可,無(wú)需重新編譯