這篇文章主要為大家詳細介紹了資料庫連接池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(); } } }
以上是Java中有關資料庫連線池c3p0配置的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!