Java 數據庫連接池c3p0 介紹
前言:
c3p0 是一個開源的數據庫連接池,實現瞭 JDBC 3 規范;本文主要介紹 c3p0 的基本使用,文中使用到的軟件版本:Java 1.8.0_191、c3p0 0.9.5.5、Spring Boot 2.3.12.RELEASE。
1、配置參數
1.1、基礎配置
配置
參數 | 默認值 | 描述 |
driverClass | null | 驅動類名稱 |
jdbcUrl | null | jdbc 連接 url |
user | null | 用戶名 |
password | null | 密碼 |
1.2、連接池大小
參數 | 默認值 | 描述 |
acquireIncrement | 3 | 連接池中的連接耗盡時,一次創建的連接個數 |
initialPoolSize | 3 | 初始連接池大小,介於 minPoolSize 和 maxPoolSize 之間 |
maxPoolSize | 15 | 最大連接數 |
minPoolSize | 3 | 最小連接數 |
1.3、連接池大小和連接存活時間
參數 | 默認值 | 描述 |
maxConnectionAge | 0 | 連接存活的最長時間(秒),0 表示沒有限制。正在使用的連接不會不受此限制。 |
maxIdleTime | 0 | 空閑連接數最大存活時間,0 表示永不過期 |
maxIdleTimeExcessConnections | 0 | 當連接數大於 minPoolSize 時,空閑連接數最大存活時間,0 表示永不過期 |
1.4、連接測試
參數 | 默認值 | 描述 |
automaticTestTable | null | 測試的表名;如果設置瞭,c3p0 將使用該表名創建一個空表,並使用其來測試連接,preferredTestQuery 參數將被忽略。 |
connectionTesterClassName | com.mchange.v2.c3p0.impl.DefaultConnectionTester | 連接測試的類名,需實現 com.mchange.v2.c3p0.ConnectionTester 或 com.mchange.v2.c3p0.QueryConnectionTester 接口。 |
idleConnectionTestPeriod | 0 | 空閑連接測試的間隔(秒)。 |
preferredTestQuery | null | 連接測試的語句;如果不設置,將使用 DatabaseMetaData 的 getTables 方法來測試,這可能時比較慢的。 |
testConnectionOnCheckin | false | 連接返回連接池時,是否測試 |
testConnectionOnCheckout | false | 從連接池獲取連接時,是否測試 |
1.5、預編譯池
參數 | 默認值 | 描述 |
maxStatements | 0 | 緩存總體預編譯語句的最大數量 |
maxStatementsPerConnection | 0 | 緩存每個連接中預編譯語句的最大數量 |
statementCacheNumDeferredCloseThreads | 0 | 清理 statement 緩存的線程數,如果需要設置,應設置為 1。一些數據庫,特別是 oracle 會在連接使用時關閉 statement,數據庫無法很好的處理這種情況,進而導致死鎖。清理的線程會在連接 |
maxStatements
和 maxStatementsPerConnection
如果都為 0,將不緩存預編譯語句。如果 maxStatements=0 and maxStatementsPerConnection>0
,maxStatementsPerConnection
起作用,不限制總的緩存數量;如果 maxStatements>0 and maxStatementsPerConnection=0
,maxStatements
起作用,不限單個連接的緩存數量。
1.6、數據庫中斷的恢復
參數 | 默認值 | 描述 |
acquireRetryAttempts | 30 | 獲取連接失敗時的重試次數 |
acquireRetryDelay | 1000 | 連接獲取重試的時間間隔(毫秒) |
breakAfterAcquireFailure | false | 嘗試獲取連接失敗時,是否聲明連接池斷開並永久關閉 |
1.7、自定義連接生命周期管理
參數 | 默認值 | 描述 |
connectionCustomizerClassName | null | 連接生命周期管理的自定義類,需實現 com.mchange.v2.c3p0.ConnectionCustomizer 接口 |
1.8、處理未提交的事務
參數 | 默認值 | 描述 |
autoCommitOnClose | false | 連接在返回連接池時是否自動提交事務。true,提交事務;false,回滾事務 |
forceIgnoreUnresolvedTransactions | false | 連接在返回連接池時,是否強制不處理事務;強烈不推薦設置為 true。 |
1.9、調試
參數 | 默認值 | 描述 |
debugUnreturnedConnectionStackTraces | false | 是否記錄活動連接的堆棧信息;如果設為 true,且 unreturnedConnectionTimeout>0,當連接借出時間 > unreturnedConnectionTimeout 時,就會打印連接的堆棧信息,並刪除該連接。 |
unreturnedConnectionTimeout | 0 | 連接未返回連接池的超時時間(秒) |
這兩個參數可用於幫助發現連接泄露。
1.10、避免熱部署內存泄露
參數 | 默認值 | 描述 |
contextClassLoaderSource | caller | 用於生成 c3p0 線程的類加載器來源,為 caller, library 或 none。caller 表示來源於連接池的調用者;library 表示來源於 c3p0 本身;none 表示使用系統類加載器 |
privilegeSpawnedThreads | false | 生成 c3p0 線程時是否使用 c3p0 庫中的 AccessControlContext;默認(false)使用連接池調用者的 AccessControlContext。 |
在應用熱部署、取消部署時,連接池可能會阻止垃圾回收進而導致內存泄露; 這兩個參數主要用於處理這種情況。
1.11、其它配置
參數 | 默認值 | 描述 |
checkoutTimeout | 0 | 從連接獲取連接的超時時間,0 表示永不超時 |
factoryClassLocation | null | c3p0 libraries的路徑,如果在本地(通常都是這樣),那麼無需設置 |
forceSynchronousCheckins | false | 連接返回連接池是否同步方式 |
maxAdministrativeTaskTime | 0 | 管理任務運行的最大時間(秒),超過改時間會終端任務;0 表示管理任務永遠不被打斷。 |
numHelperThreads | 3 | 管理線程個數 |
usesTraditionalReflectiveProxies | false | 已過期。是否使用發射動態代理的方式來實現 Connection 及 其他 JDBC 接口。 |
詳細說明可參考官網文檔:https://www.mchange.com/projects/c3p0/#configuration
2、原始連接操作
c3p0 提供 api 來訪問原始連接中的非標準接口:
- 把連接轉成
C3P0ProxyConnection
- 然後調用
rawConnectionOperation
方法
下面是獲取 PostgreSQL JDBC
驅動中 CopyManager
對象的方法:
Connection connection = (C3P0ProxyConnection) c3p0DataSource.getConnection();
C3P0ProxyConnection castConnection = (C3P0ProxyConnection) connection;
Method method = BaseConnection.class.getMethod(“getCopyAPI”, new Class[]{});
CopyManager copyManager = (CopyManager) castConnection.rawConnectionOperation(method, C3P0ProxyConnection.RAW_CONNECTION, new Object[]{});
3、使用
3.1、直接使用
3.1.1、引入依賴
<dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency>
3.1.2、使用例子
package com.abc.demo.general.dbpool; import com.mchange.v2.c3p0.ComboPooledDataSource; import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class C3p0Case { public static void main(String[] args) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setDriverClass("com.mysql.cj.jdbc.Driver"); comboPooledDataSource.setJdbcUrl("jdbc:mysql://10.40.9.11:3306/mydb?useUnicode=true&characterEncoding=UTF-8"); comboPooledDataSource.setUser("root"); comboPooledDataSource.setPassword("123456"); comboPooledDataSource.setInitialPoolSize(2); comboPooledDataSource.setMinPoolSize(2); comboPooledDataSource.setMaxPoolSize(10); comboPooledDataSource.setPreferredTestQuery("select 1"); comboPooledDataSource.setIdleConnectionTestPeriod(60); comboPooledDataSource.setTestConnectionOnCheckout(true); comboPooledDataSource.setCheckoutTimeout(1000 * 30); Connection connection = null; Statement st = null; ResultSet rs = null; try { connection = comboPooledDataSource.getConnection(); st = connection.createStatement(); rs = st.executeQuery("select version()"); if (rs.next()) { System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } finally { close(connection); } //實際使用中一般是在應用啟動時初始化數據源,應用從數據源中獲取連接;並不會關閉數據源。 comboPooledDataSource.close(); } private static void close(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
3.2、在 SpringBoot 中使用
3.1.1、引入依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
3.1.2、單數據源
application.yml 配置:
spring: datasource: c3p0: driver-class: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://10.40.9.11:3306/myDb?useUnicode=true&characterEncoding=UTF-8 user: root password: 123456 initial-pool-size: 2 min-pool-size: 2 max-pool-size: 10 preferred-test-query: select 1 idle-connection-test-period: 60 test-connection-on-checkout: true checkout-timeout: 30000
數據源配置類:
package com.abc.demo.config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Bean("dataSource") @ConfigurationProperties(prefix = "spring.datasource.c3p0") public DataSource dataSource1() { return DataSourceBuilder.create().type(ComboPooledDataSource.class).build(); } }
使用:
@Autowired private DataSource dataSource;
3.1.3、多數據源
application.yml 配置:
spring: datasource: c3p0: db1: driver-class: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://10.40.9.11:3306/myDb?useUnicode=true&characterEncoding=UTF-8 user: root password: InsYR0ot187! initial-pool-size: 2 min-pool-size: 2 max-pool-size: 10 preferred-test-query: select 1 idle-connection-test-period: 60 test-connection-on-checkout: true checkout-timeout: 30000 db2: driver-class: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://10.40.9.12:3306/myDb?useUnicode=true&characterEncoding=UTF-8 user: root password: InsYR0ot187! initial-pool-size: 2 min-pool-size: 2 max-pool-size: 10 preferred-test-query: select 1 idle-connection-test-period: 60 test-connection-on-checkout: true checkout-timeout: 30000
數據源配置類:
package com.abc.demo.config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Bean("dataSource1") @ConfigurationProperties(prefix = "spring.datasource.c3p0.db1") public DataSource dataSource1() { return DataSourceBuilder.create().type(ComboPooledDataSource.class).build(); } @Bean("dataSource2") @ConfigurationProperties(prefix = "spring.datasource.c3p0.db2") public DataSource dataSource2() { return DataSourceBuilder.create().type(ComboPooledDataSource.class).build(); } }
使用:
@Autowired @Qualifier("dataSource1") private DataSource dataSource1; @Autowired @Qualifier("dataSource2") private DataSource dataSource2;
到此這篇關於 Java 數據庫連接池c3p0 介紹的文章就介紹到這瞭,更多相關 Java 連接池c3p0 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Easycode自動化springboot的curd
- 一文詳解Spring加載properties文件的方式
- Java 數據庫連接池DBPool 介紹
- Java 數據庫連接池 DBCP 的介紹
- SpringBoot環境Druid數據源使用及特點