C3P0配置使用

C3P0: 一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

默认情况下(即没有配置连接池的情况下),Hibernate会采用内建的连接池。但这个连接池性能不佳,因此官方也只是建议仅在开发环境下使用。Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool。 

这里说一下为什么一定要使用C3P0吧:

1)hibernate官网推荐

2)  解决数据库重启后tomcat在不需要重启的情况下即可重新获得数据连接的问题。

 

下载:http://www.mchange.com/projects/c3p0/index.html

 

这里说一下如何配置,网上其实有好多,我只是根据项目需要整理了一下,一共3种,大家根据需要来配置。

 

一。JNDI(项目比较常用,最简单,与代码无关联)

1)在tomcat或者项目中引入最新版的C3P0的JAR包(我是用的是c3p0-0.9.2.1.jar)

如果启动时报类没有找到:Caused by: java.lang.NoClassDefFoundError: com/mchange/v2/ser/Indirector,

则需要加入mchange-commons-java-0.2.3.4.jar。

2)修改tomcat中的数据源配置,如下:

Xml代码   收藏代码
  1. <Resource name="jdbc/dbsource"     
  2.             type="com.mchange.v2.c3p0.ComboPooledDataSource"    
  3.             maxPoolSize="50" minPoolSize="5" acquireIncrement="2"  initialPoolSize="10"  maxIdleTime="60"  
  4.             factory="org.apache.naming.factory.BeanFactory"    
  5.             user="xxxx" password="xxxx"    
  6.             driverClass="oracle.jdbc.driver.OracleDriver"    
  7.             jdbcUrl="jdbc:oracle:thin:@192.168.x.x:1521:orcl"   
  8.             idleConnectionTestPeriod="10" />   

参数说明:

(1)idleConnectionTestPeriod

当数据库重启后或者由于某种原因进程被杀掉后,C3P0不会自动重新初始化数据库连接池,当新的请求需要访问数据库的时候,此时会报错误(因为连接失效),同时刷新数据库连接池,丢弃掉已经失效的连接,当第二个请求到来时恢复正常。

C3P0目前没有提供当获取已建立连接失败后重试次数的参数,只有获取新连接失败后重试次数的参数(acquireRetryAttempts【默认为30】 )。

要解决此问题,可以通过设置idleConnectionTestPeriod【默认为0,表示不检查 】参数折中解决,该参数的作用是设置系统自动检查连接池中连接是否正常的一个频率参数,时间单位是秒 。

 

(2)acquireIncrement

当连接池中的的连接耗尽的时候c3p0一次同时获取的连接数,也就是说,如果使用的连接数已经达到了maxPoolSize,c3p0会立即建立新的连接。

 

(3)maxIdleTime

另外,C3P0默认不会close掉不用的连接池,而是将其回收到可用连接池中,这样会导致,连接数越来越大,所以需要设置maxIdleTime【默认0,表示永远不过期】,单位是秒,maxIdleTime表示idle状态的connection能存活的最大时间。

 

3)项目中正常引入这个数据源即可,代码不需要任何修改

 

 

二。Hibernate(spring+hibernate):不推荐,完全可以使用第一种和第三种方法代替。

1)项目中引入C3P0的JAR

2)修改Hibernate中的配置(我使用的是Spring+Hibernate),如下:

Xml代码   收藏代码
  1. <bean id="sessionFactory"  
  2.         class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">  
  3.         <property name="dataSource" ref="dataSource"/>  
  4.         <property name="mappingLocations" value="${hibernate.mapping.locations}" />  
  5.         <property name="hibernateProperties">  
  6.             <props>  
  7.                 <prop key="hibernate.dialect">  
  8.                     ${hibernate.dialect}  
  9.                 </prop>  
  10.                 <prop key="hibernate.show_sql">  
  11.                     ${hibernate.show_sql}  
  12.                 </prop>  
  13.                 <prop key="hibernate.use_sql_comments">  
  14.                     ${hibernate.use_sql_comments}  
  15.                 </prop>  
  16.                   
  17.                 <prop key="hibernate.connection.provider_class">  
  18.                     org.hibernate.connection.C3P0ConnectionProvider  
  19.                 </prop>  
  20.                 <!--连接池的最小连接数 -->  
  21.                 <prop key="hibernate.c3p0.min_size">  
  22.                     5  
  23.                 </prop>  
  24.                 <!--最大连接数 -->  
  25.                 <prop key="hibernate.c3p0.max_size">  
  26.                     50  
  27.                 </prop>  
  28.                 <!--连接超时时间 -->  
  29.                 <prop key="hibernate.c3p0.timeout">  
  30.                     120  
  31.                 </prop>  
  32.                 <!--statemnets缓存大小 -->  
  33.                 <prop key="hibernate.c3p0.max_statements">  
  34.                     100  
  35.                 </prop>  
  36.                 <!--每隔多少秒检测连接是否可正常使用 -->  
  37.                 <prop key="hibernate.c3p0.idle_test_period">  
  38.                     120  
  39.                 </prop>  
  40.                 <!--当池中的连接耗尽的时候,一次性增加的连接数量,默认为3 -->  
  41.                 <prop key="hibernate.c3p0.acquire_increment">  
  42.                     2  
  43.                 </prop>  
  44.                 <!-- 每次都验证连接是否可用 -->   
  45.                 <prop key="hibernate.c3p0.validate">  
  46.                     true  
  47.                 </prop>  
  48.             </props>  
  49.         </property>  
  50.     </bean>  
  51.       

 3)这里的dataSource可以是jndi。

 

三。dataSource(spring,开发常用)

如果使用spring,同时项目中不使用jndi,又不想配置到Hibernate中,可以直接将C3P0配置到dataSource中即可,如下:

Xml代码   收藏代码
  1. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
  2.   <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property>  
  3.   <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property>  
  4.   <property name="user"><value>Kay</value></property>  
  5.   <property name="password"><value>root</value></property>  
  6.   <!--连接池中保留的最小连接数。-->  
  7.   <property name="minPoolSize" value="10" />  
  8.   <!--连接池中保留的最大连接数。Default: 15 -->  
  9.   <property name="maxPoolSize" value="100" />  
  10.   <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->  
  11.   <property name="maxIdleTime" value="1800" />  
  12.   <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->  
  13.   <property name="acquireIncrement" value="3" />  
  14.   <property name="maxStatements" value="1000" />  
  15.   <property name="initialPoolSize" value="10" />  
  16.   <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->  
  17.   <property name="idleConnectionTestPeriod" value="60" />  
  18.   <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->  
  19.   <property name="acquireRetryAttempts" value="30" />  
  20.   <property name="breakAfterAcquireFailure" value="true" />  
  21.   <property name="testConnectionOnCheckout" value="false" />  
  22.   </bean>  

 

----------------------------------------------------------------------------------------------------------------------------------------------------

public class DBManager {
	private static DBManager instance;
	public ComboPooledDataSource ds;
	private static String c3p0Properties = "c3p0.properties";
	private DBManager() {
		try {
			ds = new ComboPooledDataSource();
			ds.setDriverClass("com.mysql.jdbc.Driver");
			ds.setJdbcUrl("jdbc:mysql://localhost:3306/db?useUnicode=no&characterEncoding=utf-8&autoReconnect=true");
			ds.setUser("root");
			ds.setPassword("root");
			ds.setInitialPoolSize(30);
			ds.setMinPoolSize(20);
			ds.setMaxPoolSize(100);			
			ds.setMaxIdleTime(25000);
			ds.setAcquireIncrement(1);
			ds.setAcquireRetryAttempts(30);
			ds.setAcquireRetryDelay(1000);
			ds.setTestConnectionOnCheckin(true);
			ds.setIdleConnectionTestPeriod(18000);
			ds.setCheckoutTimeout(5000);			
		} catch (PropertyVetoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static final DBManager getInstance() {

		if (instance == null) {
			synchronized (c3p0Properties) {
				try {
					instance = new DBManager();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return instance;
	}
	public synchronized final Connection getConnection() {
		try {
			return ds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	protected void finalize() throws Throwable {
		DataSources.destroy(ds); // 关闭datasource
		super.finalize();
	}
	public void test() {
		System.out.println(this.getClass().getResourceAsStream("src"));
	}
	public static void main(String args[]) {
		DBManager.getInstance().test();
	}
}

--------------------------------------------------------------------------------------------------------------------

c3po解决 mysql 8小时问题

--------------------------------------------------------------------------------------------------------------------
	jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/***?characterEncoding=utf-8
	jdbc.username=root	
jdbc.password=**** c3p0.pool.maxPoolSize=20 c3p0.pool.minPoolSize=5 c3p0.pool.initialPoolSize=3 c3p0.pool.acquireIncrement=2 c3p0.pool.automaticTestTable=C3P0Test c3p0.pool.idleConnectionTestPeriod=60 c3p0.pool.maxIdleTime=60 c3p0.pool.checkoutTimeout=30000<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driverClassName}" /><property name="jdbcUrl" value="${jdbc.url}" /><property name="user" value="${jdbc.username}" /><property name="password" value="${jdbc.password}" /><property name="maxPoolSize" value="${c3p0.pool.maxPoolSize}" /><property name="minPoolSize" value="${c3p0.pool.minPoolSize}" /><property name="initialPoolSize" value="${c3p0.pool.initialPoolSize}" /><property name="acquireIncrement" value="${c3p0.pool.acquireIncrement}" /><!--解决Mysql 8小时问题 --><property name="automaticTestTable" value="${c3p0.pool.automaticTestTable}"/><property name="idleConnectionTestPeriod" value="${c3p0.pool.idleConnectionTestPeriod}"/><!--设置为2个小时 --><property name="maxIdleTime" value="${c3p0.pool.maxIdleTime}"/> <!--获取连接超时毫秒为单位---><property name="checkoutTimeout" value="${c3p0.pool.checkoutTimeout}"/></bean>





--------------------------------------------------------------------------------------------------------------------

//初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 initialPoolSize  
    cpds.setInitialPoolSize(initialPoolSize);   
   
//连接池中保留的最大连接数。Default: 15 maxPoolSize   
    cpds.setMaxPoolSize(maxPoolSize);
  
//连接池中保留的最小连接数。   
    cpds.setMinPoolSize(minPoolSize);
    
//获得连接的最大等待毫秒数。Default: 1000 acquireRetryDelay
    cpds.setAcquireRetryDelay(acquireRetryDelay);
    
//最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 maxIdleTime   
    cpds.setMaxIdleTime(maxIdleTime);
   
//当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 acquireIncrement   
    cpds.setAcquireIncrement(3);   
   
//每60秒检查所有连接池中的空闲连接。Default: 0 idleConnectionTestPeriod   
    cpds.setIdleConnectionTestPeriod(60);
  
//连接关闭时默认将所有未提交的操作回滚。Default: false autoCommitOnClose   
    cpds.setAutoCommitOnClose(true);
 
//JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0
    cpds.setMaxStatements(1);

    
//maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数
    cpds.setMaxStatementsPerConnection(100);

    
//定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:测试的表必须在初始数据源的时候就存在。Default: null preferredTestQuery  
    cpds.setPreferredTestQuery("select sysdate from dual");   
    
// 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的   
// 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable   
// 等方法来提升连接测试的性能。Default: false testConnectionOnCheckout   
    cpds.setTestConnectionOnCheckout(true);
    
//如果设为true那么在取得连接的同时将校验连接的有效性。Default: false testConnectionOnCheckin   
    cpds.setTestConnectionOnCheckin(true);   
   
 //定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 acquireRetryAttempts   
    cpds.setAcquireRetryAttempts(30);     
    
//获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效   
//保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试   
//获取连接失败后该数据源将申明已断开并永久关闭。Default: false breakAfterAcquireFailure   
    cpds.setBreakAfterAcquireFailure(false);   

//两次连接中间隔时间,单位毫秒。Default: 1000 acquireRetryDelay
  cpds.setAcquireRetryDelay(60000);

//java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.getClob(异常解决办法
最近遇到了一个头痛的问题,可能大家也遇到过。经过多番的询问与查找,终于知道问题原因的所在:异常内容如下:

//java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.getClob(Ljava/lang/String;)Ljava/sql/Clob;

问题原因:Oracle驱动版本不对

解决办法:在Oracle服务器上找到这个驱动,然后cp到Apache的lib目录下,并同是修改环境变量classpath,保证这个lib/classes12.jar在最前面;修改完后,重新启动服务,问题就可以解决。


 

 

 

--------------------------------------------------------------------------------------------------------------------
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值