Java建立数据库连接池
作者:网络转载 发布时间:[ 2016/12/13 11:08:43 ] 推荐标签:数据库 Java
/**
* 查找连接池中所有的连接,查找一个可用的数据库连接, 如果没有可用的连接,返回 null
*
* @return 返回一个可用的数据库连接
*/
private Connection findFreeConnection() throws SQLException {
Connection conn = null;
PooledConnection pConn = null;
// 获得连接池向量中所有的对象
Enumeration enumerate = connections.elements();
// 遍历所有的对象,看是否有可用的连接
while (enumerate.hasMoreElements()) {
pConn = (PooledConnection) enumerate.nextElement();
if (!pConn.isBusy()) {
// 如果此对象不忙,则获得它的数据库连接并把它设为忙
conn = pConn.getConnection();
pConn.setBusy(true);
// 测试此连接是否可用
if (!testConnection(conn)) {
// 如果此连接不可再用了,则创建一个新的连接,
// 并替换此不可用的连接对象,如果创建失败,返回 null
try {
conn = newConnection();
} catch (SQLException e) {
System.out.println(" 创建数据库连接失败! " + e.getMessage());
return null;
}
pConn.setConnection(conn);
}
break; // 己经找到一个可用的连接,退出
}
}
System.out.println("--------------:获得一个可用的数据库连接(findFreeConnection)");
return conn;// 返回找到到的可用连接
}
/**
* 测试一个连接是否可用,如果不可用,关掉它并返回 false 否则可用返回 true
*
* @param conn
* 需要测试的数据库连接
* @return 返回 true 表示此连接可用, false 表示不可用
*/
private boolean testConnection(Connection conn) {
try {
// 判断测试表是否存在
if (testTable.equals("")) {
// 如果测试表为空,试着使用此连接的 setAutoCommit() 方法
// 来判断连接否可用(此方法只在部分数据库可用,如果不可用 ,
// 抛出异常)。注意:使用测试表的方法更可靠
conn.setAutoCommit(true);
} else {// 有测试表的时候使用测试表测试
// check if this connection is valid
Statement stmt = conn.createStatement();
stmt.execute("select count(*) from " + testTable);
}
} catch (SQLException e) {
// 上面抛出异常,此连接己不可用,关闭它,并返回 false;
closeConnection(conn);
return false;
}
// 连接可用,返回 true
System.out.println("--------------:测试数据库连接是否可用");
return true;
}
/**
* 此函数返回一个数据库连接到连接池中,并把此连接置为空闲。 所有使用连接池获得的数据库连接均应在不使用此连接时返回它。
*
* @param 需返回到连接池中的连接对象
*/
public void returnConnection(Connection conn) {
System.out.println("--------------:返回到连接池中的连接对象");
// 确保连接池存在,如果连接没有创建(不存在),直接返回
if (connections == null) {
System.out.println(" 连接池不存在,无法返回此连接到连接池中 !");
return;
}
PooledConnection pConn = null;
Enumeration enumerate = connections.elements();
// 遍历连接池中的所有连接,找到这个要返回的连接对象
while (enumerate.hasMoreElements()) {
pConn = (PooledConnection) enumerate.nextElement();
// 先找到连接池中的要返回的连接对象
if (conn == pConn.getConnection()) {
// 找到了 , 设置此连接为空闲状态
pConn.setBusy(false);
break;
}
}
}
/**
* 刷新连接池中所有的连接对象
*
*/
public synchronized void refreshConnections() throws SQLException {
// 确保连接池己创新存在
if (connections == null) {
System.out.println(" 连接池不存在,无法刷新 !");
return;
}
PooledConnection pConn = null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
// 获得一个连接对象
pConn = (PooledConnection) enumerate.nextElement();
// 如果对象忙则等 5 秒 ,5 秒后直接刷新
if (pConn.isBusy()) {
wait(5000); // 等 5 秒
}
// 关闭此连接,用一个新的连接代替它。
closeConnection(pConn.getConnection());
pConn.setConnection(newConnection());
pConn.setBusy(false);
}
}
/**
* 关闭连接池中所有的连接,并清空连接池。
*/
public synchronized void closeConnectionPool() throws SQLException {
// 确保连接池存在,如果不存在,返回
if (connections == null) {
System.out.println(" 连接池不存在,无法关闭 !");
return;
}
PooledConnection pConn = null;
Enumeration enumerate = connections.elements();
while (enumerate.hasMoreElements()) {
pConn = (PooledConnection) enumerate.nextElement();
// 如果忙,等 5 秒
if (pConn.isBusy()) {
wait(5000); // 等 5 秒
}
// 5 秒后直接关闭它
closeConnection(pConn.getConnection());
// 从连接池向量中删除它
connections.removeElement(pConn);
}
// 置连接池为空
connections = null;
}
/**
* 关闭一个数据库连接
*
* @param 需要关闭的数据库连接
*/
private void closeConnection(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
System.out.println(" 关闭数据库连接出错: " + e.getMessage());
}
}
/**
* 使程序等待给定的毫秒数
*
* @param 给定的毫秒数
*/
private void wait(int mSeconds) {
try {
Thread.sleep(mSeconds);
} catch (InterruptedException e) {
}
}
/**
*
* 内部使用的用于保存连接池中连接对象的类 此类中有两个成员,一个是数据库的连接,另一个是指示此连接是否 正在使用的标志。
*/
class PooledConnection {
Connection connection = null;// 数据库连接
boolean busy = false; // 此连接是否正在使用的标志,默认没有正在使用
// 构造函数,根据一个 Connection 构告一个 PooledConnection 对象
public PooledConnection(Connection connection) {
this.connection = connection;
}
// 返回此对象中的连接
public Connection getConnection() {
return connection;
}
// 设置此对象的,连接
public void setConnection(Connection connection) {
this.connection = connection;
}
// 获得对象连接是否忙
public boolean isBusy() {
return busy;
}
// 设置对象的连接正在忙
public void setBusy(boolean busy) {
this.busy = busy;
}
}
}
然后新建一个测试类:
package com.test.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.test.util.ConnectionPoolUtil;
public class Test {
/**
* @param args
* @throws Exception
*/
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。
相关推荐
Java性能测试有哪些不为众人所知的原则?Java设计模式??装饰者模式谈谈Java中遍历Map的几种方法Java Web入门必知你需要理解的Java反射机制知识总结编写更好的Java单元测试的7个技巧编程常用的几种时间戳转换(java .net 数据库)适合Java开发者学习的Python入门教程Java webdriver如何获取浏览器新窗口中的元素?Java重写与重载(区别与用途)Java变量的分类与初始化JavaScript有这几种测试分类Java有哪四个核心技术?给 Java开发者的10个大数据工具和框架Java中几个常用设计模式汇总java生态圈常用技术框架、开源中间件,系统架构及经典案例等
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11热门文章
常见的移动App Bug??崩溃的测试用例设计如何用Jmeter做压力测试QC使用说明APP压力测试入门教程移动app测试中的主要问题jenkins+testng+ant+webdriver持续集成测试使用JMeter进行HTTP负载测试Selenium 2.0 WebDriver 使用指南