连接池方案:C3P0+Apache dbutils

C3P0和spring dbcp差不多,是一个连接池解决方案,其相比dbpc多出的一个功能是能够通过配置使超时不用的连接释放。C3P0中主要使用的是ComboPooledDataSource类,用其getConnection方法来得到java.sql.Connection,此时的connectin调用close方法并不会关闭连接,而是返回到连接池。可以通过ComboPooledDataSource的getNumConnections方法来查看close前后的连接数目来证实。


spring整合C3P0的主要配置参数如下

<!-- c3p0连接池配置 -->  
     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
          <property name="user" value="wemedia"/>  
          <property name="password" value="qzGD+eAI8Hr6dHM"/>  
          <property name="driverClass" value="com.mysql.jdbc.Driver"/>  
          <property name="jdbcUrl" value="jdbc:mysql://wemedia.db.spaces.sohu.com:3306/wemedia?useUnicode=true&characterEncoding=UTF-8"/>  
           <!--连接池中保留的最大连接数。默认值: 15 -->   
          <property name="maxPoolSize" value="20"/>  
          <!-- 连接池中保留的最小连接数,默认为:3-->  
          <property name="minPoolSize" value="5"/>  
          <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3-->  
          <property name="initialPoolSize" value="10"/>  
          <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->   
          <property name="maxIdleTime" value="120"/>  
          <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->   
          <property name="checkoutTimeout" value="5000"/>  
          <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->   
          <property name="acquireIncrement" value="2"/>  
         <!--定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次-->   
          <property name="acquireRetryAttempts" value="10"/>  
          <!--重新尝试的时间间隔,默认为:1000毫秒-->   
          <property name="acquireRetryDelay" value="1000" />  
          <!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->   
          <property name="idleConnectionTestPeriod" value="60"/>  
     </bean>  	

需要说明下initialPoolSize参数是在第一次建立连接的时候,会产生initialPoolSize个连接,并不是初始化的时候。


如果不用dbutils来结合的话,就像使用jdbc那样用即可了。但是需要编码来管理连接的创建和释放,这部分和sql语句结果集的处理(比如封装成bean),Apache的dbutils又做得比较好,所以想到了将两者结合使用。

package com.sohu.wemedia.space.util;

import java.sql.Connection;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.ArrayHandler;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * C3P0连接池的工具类,借助apache.commons.dbutils
 * 
 * @author ranjiehu
 *
 */
public class C3P0Util {

	/**
	 * 返回Object数组,需要自己转换类型
	 * 
	 * @param sql
	 * @param dataSource
	 * @param resultSetHandler
	 * @return
	 */
	public static Object[] getByArrayHandler(String sql,
			ComboPooledDataSource dataSource, ArrayHandler arrayHandler) {
		Connection connection = null;
		QueryRunner queryRunner = new QueryRunner();
		try {
			connection = dataSource.getConnection();
			Object[] rs = queryRunner.query(connection, sql, arrayHandler);
			return rs;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				connection.close();// 返回资源到连接池,假close
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 返回泛型对象,根据ResultSetHandler来转换
	 * 
	 * @param sql
	 * @param dataSource
	 * @param resultSetHandler
	 * @return
	 */
	public static <T> T getByResultSetHandler(String sql,
			ComboPooledDataSource dataSource,
			ResultSetHandler<T> resultSetHandler) {
		Connection connection = null;
		QueryRunner queryRunner = new QueryRunner();
		try {
			connection = dataSource.getConnection();
			T rs = (T) queryRunner.query(connection, sql, resultSetHandler);
			return rs;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				connection.close();// 返回资源到连接池,假close
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

向上暴露数据源、sql、以及各种处理方法(各种ResultSetHandler及其子集),使用时将Spring中配置的ComboPooledDataSource代表的数据源传入即可。

比如将查询结果转为对象的list,如下:

List<WeekRank> list = C3P0Util.getByResultSetHandler(sql,
					dataSource, new ResultSetHandler<List<WeekRank>>() {
						@Override
						public List<WeekRank> handle(ResultSet paramResultSet)
								throws SQLException {
							List<WeekRank> list = new ArrayList<WeekRank>();
							int i = 1;
							while (paramResultSet.next()) {
								WeekRank weekRank = new WeekRank();
								weekRank.setRank(i++);
								weekRank.setUserId(paramResultSet
										.getLong("user_id"));
								weekRank.setPlayCount(paramResultSet
										.getLong("play_count"));
								list.add(weekRank);
							}
							return list;
						}
					});


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值