几种Java数据库连接池实现(三)<1>

package pool;
import java.lang.reflect.*;
import java.sql.*;
/**
*
* 定义数据库连接的代理类
*
*/
public class _Connection implements InvocationHandler {
// 定义连接
private Connection conn = null;
// 定义监控连接创建的语句
private Statement statRef = null;
private PreparedStatement prestatRef = null;
// 是否支持事务标志
private boolean supportTransaction = false;
// 数据库的忙状态
private boolean isFree = false;
// 最后一次访问时间
long lastAccessTime = 0;
// 定义要接管的函数的名字
String CREATESTATE = "createStatement";
String CLOSE = "close";
String PREPARESTATEMENT = "prepareStatement";
String COMMIT = "commit";
String ROLLBACK = "rollback";
/**
* 构造函数,采用私有,防止被直接创建
*
* @param param
* 连接参数
*/
private _Connection(ConnectionParam param) { // 记录日志
try {
// 创建连接
Class.forName(param.getDriver()).newInstance();
conn = DriverManager.getConnection(param.getUrl(), param.getUser(),
param.getPassword());
DatabaseMetaData dm = null;
dm = conn.getMetaData();
// 判断是否支持事务
supportTransaction = dm.supportsTransactions();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
* @see java.lang.reflect.InvocationHandler#invoke
* (java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
// 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if (CLOSE.equals(method.getName())) {
// 设置不使用标志
setIsFree(false);
// 检查是否有后续工作,清除该连接无用资源
if (statRef != null)
statRef.close();
if (prestatRef != null)
prestatRef.close();
return null;
}
// 判断是使用了createStatement语句
if (CREATESTATE.equals(method.getName())) {
obj = method.invoke(conn, args);
statRef = (Statement) obj;// 记录语句
return obj;
}
// 判断是使用了prepareStatement语句
if (PREPARESTATEMENT.equals(method.getName())) {
obj = method.invoke(conn, args);
prestatRef = (PreparedStatement) obj;
return obj;
}
// 如果不支持事务,就不执行该事物的代码
if ((COMMIT.equals(method.getName()) || ROLLBACK.equals(method
.getName()))
&& (!isSupportTransaction()))
return null;
obj = method.invoke(conn, args);
// 设置最后一次访问时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
return obj;
}

/**
* 创建连接的工厂,只能让工厂调用
* @param factory
* 要调用工厂,并且一定被正确初始化
* @param param
* 连接参数
* @return 连接
*
*/
public static _Connection getConnection(ConnectionFactory factory,
ConnectionParam param) {
if (factory.isCreate()) {// 判断是否正确初始化的工厂
_Connection _conn = new _Connection(param);
return _conn;
} else {
return null;
}
}
public Connection getFreeConnection() {
// 返回数据库连接conn的接管类,以便截住close方法
Connection conn2 = (Connection) Proxy.newProxyInstance(conn.getClass()
.getClassLoader(), conn.getClass().getInterfaces(), this);
return conn2;
}
/**
*
* 该方法真正的关闭了数据库的连接
*
* @throws SQLException
*
*/
void close() throws SQLException {
// 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
conn.close();
}
public void setIsFree(boolean value) {
isFree = value;
}
public boolean isFree() {
return isFree;
}
/**
*
* 判断是否支持事务
*
* @return boolean
*
*/
public boolean isSupportTransaction() {
return supportTransaction;
}
}

package pool;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class ConnectionFactory {
private static ConnectionFactory m_instance = null;
// 在使用的连接池
private LinkedHashSet<_Connection> ConnectionPool = null;
// 空闲连接池
private LinkedHashSet<_Connection> FreeConnectionPool = null;
// 最大连接数
private int MaxConnectionCount = 4;
// 最小连接数
private int MinConnectionCount = 2;
// 当前连接数
private int current_conn_count = 0;
// 连接参数
private ConnectionParam connparam = null;
// 是否创建工厂的标志
private boolean isflag = false;
// 是否支持事务
private boolean supportTransaction = false;
// 定义管理策略
private int ManageType = 0;
private ConnectionFactory() {
ConnectionPool = new LinkedHashSet<_Connection>();
FreeConnectionPool = new LinkedHashSet<_Connection>();
}
/**
*
* 使用指定的参数创建一个连接池
*
*/
public ConnectionFactory(ConnectionParam param, FactoryParam fparam)
throws SQLException {
// 不允许参数为空
if ((param == null) || (fparam == null))
throw new SQLException("ConnectionParam和FactoryParam不能为空");
if (m_instance == null) {
synchronized (ConnectionFactory.class) {
if (m_instance == null) {
// new instance
// 参数定制
m_instance = new ConnectionFactory();
m_instance.connparam = param;
m_instance.MaxConnectionCount = fparam.getMaxConn();
m_instance.MinConnectionCount = fparam.getMinConn();
m_instance.ManageType = fparam.getType();
m_instance.isflag = true;
// 初始化,创建MinConnectionCount个连接
System.out.println("connection factory 创建!");
try {
for (int i = 0; i < m_instance.MinConnectionCount; i++) {
_Connection _conn = _Connection.getConnection(
m_instance, m_instance.connparam);
if (_conn == null)
continue;
System.out.println("connection创建");
m_instance.FreeConnectionPool.add(_conn);// 加入空闲连接池
m_instance.current_conn_count++;
// 标志是否支持事务
m_instance.supportTransaction = _conn
.isSupportTransaction();
}
} catch (Exception e) {
e.printStackTrace();
}
// 根据策略判断是否需要查询
if (m_instance.ManageType != 0) {
Thread t = new Thread(
new FactoryMangeThread(m_instance));
t.start();
}
}
}
}
}

/**
*
* 标志工厂是否已经创建
*
* @return boolean
*
*/
public boolean isCreate() {
return m_instance.isflag;
}

/**
*
* 从连接池中取一个空闲的连接
*
* @return Connection
*
* @throws SQLException
*
*/
public synchronized Connection getFreeConnection() throws SQLException {
Connection conn = null;
// 获取空闲连接
Iterator iter = m_instance.FreeConnectionPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
// 找到未用连接
if (!_conn.isFree()) {
conn = _conn.getFreeConnection();
_conn.setIsFree(true);
// 移出空闲区
m_instance.FreeConnectionPool.remove(_conn);
// 加入连接池
m_instance.ConnectionPool.add(_conn);
break;
}
}
// 检查空闲池是否为空
if (m_instance.FreeConnectionPool.isEmpty()) {
// 再检查是否能够分配
if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
// 新建连接到空闲连接池
int newcount = 0;
// 取得要建立的数目
if (m_instance.MaxConnectionCount
- m_instance.current_conn_count >= m_instance.MinConnectionCount) {
newcount = m_instance.MinConnectionCount;
} else {
newcount = m_instance.MaxConnectionCount
- m_instance.current_conn_count;
}
// 创建连接
for (int i = 0; i < newcount; i++) {
_Connection _conn = _Connection.getConnection(m_instance,
m_instance.connparam);
m_instance.FreeConnectionPool.add(_conn);
m_instance.current_conn_count++;
}
} else {// 如果不能新建,检查是否有已经归还的连接
iter = m_instance.ConnectionPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {
conn = _conn.getFreeConnection();
_conn.setIsFree(false);
m_instance.ConnectionPool.remove(_conn);
m_instance.FreeConnectionPool.add(_conn);
break;
}
}
}
}// if (FreeConnectionPool.isEmpty())
// 再次检查是否能分配连接
if (conn == null) {
iter = m_instance.FreeConnectionPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {
conn = _conn.getFreeConnection();
_conn.setIsFree(true);
m_instance.FreeConnectionPool.remove(_conn);
m_instance.ConnectionPool.add(_conn);
break;
}
}
if (conn == null)// 如果不能则说明无连接可用
throw new SQLException("没有可用的数据库连接");
}
System.out.println("get connection");
return conn;
}

/**
*
* 关闭该连接池中的所有数据库连接
*
* @throws SQLException
*
*/
public synchronized void close() throws SQLException {
this.isflag = false;
SQLException excp = null;
// 关闭空闲池
Iterator iter = m_instance.FreeConnectionPool.iterator();
while (iter.hasNext()) {
try {
((_Connection) iter.next()).close();
System.out.println("close connection:free");
m_instance.current_conn_count--;
} catch (Exception e) {
if (e instanceof SQLException)
excp = (SQLException) e;
}
}
// 关闭在使用的连接池
iter = m_instance.ConnectionPool.iterator();
while (iter.hasNext()) {
try {
((_Connection) iter.next()).close();
System.out.println("close connection:inused");
m_instance.current_conn_count--;
} catch (Exception e) {
if (e instanceof SQLException)
excp = (SQLException) e;
}
}
if (excp != null)
throw excp;
}

/**
*
* 返回是否支持事务
*
* @return boolean
*
*/
public boolean isSupportTransaction() {
return m_instance.supportTransaction;
}

/**
*
* 连接池调度管理
*
*
*
*/
public void schedule() {
//Connection conn = null;
// 再检查是否能够分配
Iterator iter = null;
// 检查是否有已经归还的连接
iter = m_instance.ConnectionPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {
//conn = _conn.getFreeConnection();
_conn.setIsFree(false);
m_instance.ConnectionPool.remove(_conn);
m_instance.FreeConnectionPool.add(_conn);
break;
}
}

if (m_instance.current_conn_count < m_instance.MaxConnectionCount) {
// 新建连接到空闲连接池
int newcount = 0;
// 取得要建立的数目
if (m_instance.MaxConnectionCount - m_instance.current_conn_count >= m_instance.MinConnectionCount) {
newcount = m_instance.MinConnectionCount;
} else {
newcount = m_instance.MaxConnectionCount
- m_instance.current_conn_count;
}
// 创建连接
for (int i = 0; i < newcount; i++) {
_Connection _conn = _Connection.getConnection(m_instance,
m_instance.connparam);
m_instance.FreeConnectionPool.add(_conn);
m_instance.current_conn_count++;
}
}
}
}

package pool;

import java.io.Serializable;

public class ConnectionParam implements Serializable {
private static final long serialVersionUID = 1L;

private String driver; // 数据库驱动程序

private String url; // 数据连接的URL

private String user; // 数据库用户名

private String password; // 数据库密码

/**
*
* 唯一的构造函数,需要指定连接的四个必要参数
*
* @param driver
* 数据驱动
*
* @param url
* 数据库连接url
*
* @param user
* 用户名
*
* @param password
* 密码
*
*/
public ConnectionParam(String driver, String url, String user,
String password) {
this.driver = driver;
this.url = url;
this.user = user;
this.password = password;
}

public String getDriver() {
return driver;
}

public String getPassword() {
return password;
}

public String getUrl() {
return url;
}

public String getUser() {
return user;
}

public void setDriver(String driver) {
this.driver = driver;
}

public void setPassword(String password) {
this.password = password;
}

public void setUrl(String url) {
this.url = url;
}

public void setUser(String user) {
this.user = user;
}

/**
*
* @see java.lang.Object#clone()
*
*/
public Object clone() {
ConnectionParam param = new ConnectionParam(driver, url, user, password);
return param;
}

/**
*
* @see java.lang.Object#equals(java.lang.Object)
*
*/
public boolean equals(Object obj) {
if (obj instanceof ConnectionParam) {
ConnectionParam param = (ConnectionParam) obj;
return ((driver.compareToIgnoreCase(param.getDriver()) == 0)
&& (url.compareToIgnoreCase(param.getUrl()) == 0)
&& (user.compareToIgnoreCase(param.getUser()) == 0) && (password
.compareToIgnoreCase(param.getPassword()) == 0));
}
return false;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据库连接池是一种管理和复用数据库连接的技术,它可以减少每次请求时创建和释放数据库连接的开销,提高系统性能和资源利用率。下面是数据库连接池的工作原理: 1. 初始化连接池:在应用程序启动时,连接池会初始化一定数量的数据库连接,并将它们存储在连接池中。 2. 请求连接:当应用程序需要与数据库进行交互时,它从连接池中请求一个可用的数据库连接。 3. 处理事务:应用程序使用获取到的数据库连接执行数据库操作,包括查询、插入、更新等。 4. 释放连接:事务完成后,应用程序将数据库连接释放回连接池,而不是直接关闭它。 5. 连接重用:下一个请求到来时,应用程序可以再次从连接池获取可用的数据库连接,而不是重新创建连接。 常用的数据库连接池有以下几种: 1. Apache Commons DBCP:Apache Commons DBCP是一个开源的数据库连接池库,具有较高的性能和稳定性。 2. C3P0:C3P0是一个流行的Java数据库连接池库,支持JDBC 3.0和JDBC 4.0规范。 3. HikariCP:HikariCP是一个轻量级且高性能的数据库连接池,被认为是目前最快的Java连接池。 4. BoneCP:BoneCP是另一个高性能的数据库连接池,具有快速启动和低资源消耗的特点。 选择适合的数据库连接池取决于具体的应用程序需求和性能要求。需要注意的是,连接池的配置参数也很重要,如最大连接数、最小空闲连接数、连接超时时间等,需要根据实际情况进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值