Mysql结合C3p0配置动态数据源

1.首先,先获取三个依赖包: c3p0-0.9.5.1.jar  ,  mysql-connector-java-5.1.41-bin.jar  ,  mchange-commons-java-0.2.10.jar

依赖包

2.自定义线程池

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DynamicDataSourcePool {
	private static final Log log = LogFactory.getLog(DynamicDataSourcePool.class);
	private ComboPooledDataSource pool = null;// 申明C3p0数据连接池变量

	/**
	 * 默认的构造方法
	 * 
	 * @param userName
	 *            数据库用户名
	 * @param pass
	 *            数据库密码
	 * @param url
	 *            连接的url
	 * @param driverClass
	 *            数据驱动
	 */
	public DynamicDataSourcePool(String userName, String pass, String url, String driverClass) {
		try {
			this.pool = new ComboPooledDataSource();// 创建对象
			this.pool.setDriverClass(driverClass);// 设置驱动
			this.pool.setJdbcUrl(url); // 设置连接的url
			this.pool.setUser(userName);// 设置数据库用户名
			this.pool.setPassword(pass);// 设置数据库密码
			this.pool.setAcquireIncrement(3);// 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数
			this.pool.setAutoCommitOnClose(false);// 连接关闭时默认将所有未提交的操作回滚
			this.pool.setBreakAfterAcquireFailure(false);// 获取连接失败后该数据源将申明已断开并永久关闭
			this.pool.setCheckoutTimeout(1000);// 当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。
			this.pool.setIdleConnectionTestPeriod(60);// 每60秒检查所有连接池中的空闲连接
			this.pool.setInitialPoolSize(10);// 初始化时获取10个连接,取值应在minPoolSize与maxPoolSize之间
			this.pool.setMaxPoolSize(40);// 连接池中保留的最大连接数
			this.pool.setMinPoolSize(5);// 连接池最小连接数
			this.pool.setMaxIdleTime(60);// 最大空闲时间,60秒内未使用则连接被丢弃
			this.pool.setNumHelperThreads(3);// c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能通过多线程实现多个操作同时被执行
			log.info("数据库连接池初始化成功");
		} catch (PropertyVetoException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 得到连接
	 * 
	 * @return
	 */
	public Connection getConnection() {
		try {
			return this.pool.getConnection();
		} catch (SQLException e) {
			log.info("获取连接异常");
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 关闭
	 */
	public void destroy() {
		if (null != this.pool)
			this.pool.close();
	}
}

3.对线程池的封装,作为一个factory工具类使用,如下包含了测试方法main()


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;

import org.apache.ibatis.session.SqlSession;

public class DynamicDataSourcePoolFactory {
	private static Hashtable<String, DynamicDataSourcePool> hashtable = null;
	private static DynamicDataSourcePoolFactory dataSourcePoolFactory;

	private DynamicDataSourcePoolFactory() {
	}

	public static DynamicDataSourcePoolFactory getInstance() {
		if (null == dataSourcePoolFactory) {
			hashtable = new Hashtable<String, DynamicDataSourcePool>();
			dataSourcePoolFactory = new DynamicDataSourcePoolFactory();
		}
		return dataSourcePoolFactory;
	}

	/**
	 * 绑定连接池
	 * 
	 * @param key
	 *            连接池的名称必须唯一
	 * @param dataSourcePool
	 *            对应的连接池
	 */
	public void bind(String key, DynamicDataSourcePool dataSourcePool) {
		if (IsBePool(key))
			getDynamicDataSourcePool(key).destroy();
		hashtable.put(key, dataSourcePool);
	}

	/**
	 * 重新绑定连接池
	 * 
	 * @param key
	 *            连接池的名称必须唯一
	 * @param dataSourcePool
	 *            对应的连接池
	 */
	public void rebind(String key, DynamicDataSourcePool dataSourcePool) {
		if (IsBePool(key))
			getDynamicDataSourcePool(key).destroy();
		hashtable.put(key, dataSourcePool);
	}

	/**
	 * 删除动态数据连接池中名称为key的连接池
	 * 
	 * @param key
	 */
	public void unbind(String key) {
		if (IsBePool(key))
			getDynamicDataSourcePool(key).destroy();
		hashtable.remove(key);
	}

	/**
	 * 查找动态数据连接池中是否存在名称为key的连接池
	 * 
	 * @param key
	 * @return
	 */
	public boolean IsBePool(String key) {
		return hashtable.containsKey(key);
	}

	/**
	 * 根据key返回key对应的连接池
	 * 
	 * @param key
	 * @return
	 */
	public DynamicDataSourcePool getDynamicDataSourcePool(String key) {
		if (!IsBePool(key))
			return null;
		return (DynamicDataSourcePool) hashtable.get(key);

	}

	// 释放连接
	public static void release(Connection conn, Statement st, ResultSet rs) {
		release(null, conn, st, rs);
	}

	// 释放连接
	public static void release(SqlSession sqls, Connection conn, Statement st, ResultSet rs) {
		if (sqls != null) {
			try {
				// 关闭SqlSession
				sqls.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			sqls = null;
		}
		if (rs != null) {
			try {
				// 关闭存储查询结果的ResultSet对象
				rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			rs = null;
		}
		if (st != null) {
			try {
				// 关闭负责执行SQL命令的Statement对象
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		if (conn != null) {
			try {
				// 将Connection连接对象还给数据库连接池
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println("---> 释放资源成功");
	}
	
	// 测试
	public static void main(String[] args) { 
		String localurl = "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=true";
		DynamicDataSourcePool dataSourcePool1 = new DynamicDataSourcePool("root", "123456", localurl,
				"com.mysql.jdbc.Driver");
		DynamicDataSourcePoolFactory factory = DynamicDataSourcePoolFactory.getInstance();
		factory.bind("mysql", dataSourcePool1);
		/* 判读是否存在这个连接池 */
		System.out.println(factory.IsBePool("mysql"));
		/* 得到连接 */
		Connection connection161 = factory.getDynamicDataSourcePool("mysql").getConnection();
		
		PreparedStatement st = null;
		ResultSet rs = null;
		String sql = "show databases";
		try {
			st = connection161.prepareStatement(sql);
			rs = st.executeQuery();
			while(rs.next())
				System.out.println(rs.getString("Database"));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			release(connection161, st, rs);
		}
		
	}
}

4.注意:不是本地的mysql时,mysql的用户要被授予远程访问权限。

5.如果出现了mybatis使用过程中出现dao层卡住的情况,先打开log4j的trace日志功能,你应该就能看到具体什么问题了,比如说c3p0的默认lian连接池数量是15,到达峰值后dao执行的sql就会卡住了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!关于Spring中配置c3p0MySQL数据源的问题,可以参考以下步骤进行配置: 1. 在pom.xml中添加相关依赖: ``` <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> ``` 2. 在Spring配置文件中配置数据源: ``` <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.cj.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" /> <property name="user" value="root" /> <property name="password" value="123456" /> <property name="maxPoolSize" value="30" /> <property name="minPoolSize" value="10" /> <property name="initialPoolSize" value="10" /> <property name="maxIdleTime" value="1800" /> <property name="acquireIncrement" value="3" /> </bean> ``` 其中,`driverClass`为MySQLJDBC驱动类,`jdbcUrl`为数据库连接URL,`user`和`password`为数据库用户名和密码,`maxPoolSize`为最大连接数,`minPoolSize`为最小连接数,`initialPoolSize`为初始连接数,`maxIdleTime`为最大空闲时间,`acquireIncrement`为每次获取连接时增加的连接数。 3. 在DAO层中使用数据源: ``` @Repository public class UserDaoImpl implements UserDao { @Autowired private DataSource dataSource; private JdbcTemplate jdbcTemplate; @PostConstruct public void init() { jdbcTemplate = new JdbcTemplate(dataSource); } // 接下来可以使用jdbcTemplate执行SQL操作 // ... } ``` 以上是一个基本的配置示例,具体根据自己的需求进行调整。希望能够帮到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值