版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BAStriver/article/details/82982337
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的用户要被授予远程访问权限。