`

数据库连接池

阅读更多

连接工厂 ConnectionFactory

 

写道
package myConnPool;

import java.util.LinkedHashSet;
import java.sql.*;
import java.util.Iterator;

public class ConnectionFactory {
private static ConnectionFactory connFactory = null;
private LinkedHashSet connPool = null;// 在使用的连接池
private LinkedHashSet freeConnPool = null;// 空闲连接池
private int maxConnCount = 4;//最大连接数
private int minConnCount = 2; // 最小连接数
private int current_conn_count = 0;// 当前连接数
private boolean isflag = false;// 是否创建工厂的标志
private ConnectionFactory(){}
public ConnectionFactory(ConnectionParam param) throws SQLException {
if (connFactory == null) {
synchronized (ConnectionFactory.class) {
if (connFactory == null) {
connFactory=new ConnectionFactory();
connFactory.connPool = new LinkedHashSet();
connFactory.freeConnPool = new LinkedHashSet();
connFactory.maxConnCount = param.getMaxConn();
connFactory.minConnCount = param.getMinConn();
connFactory.isflag = true;
try {// 初始化,创建minConnCount个连接
for (int i = 0; i < connFactory.minConnCount; i++) {
_Connection _conn = _Connection
.getConnection(connFactory);
connFactory.freeConnPool.add(_conn);// 加入空闲连接池
connFactory.current_conn_count++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// 标志工厂是否已经创建
public boolean isCreate() {
return connFactory.isflag;
}

/* 从连接池中取一个空闲的连接
* 先遍历空闲连接池,看看是否有空闲连接
* 如果能得到连接,得到连接后,从空闲连接池移除该链接,然后加入到当前连接池
* 判断连空闲连接池是否为空
* 如果空闲连接池为空,并且当前连接还没达到最大连接数,则创建新的连接,加入空闲连接池
* 然后检查当前连接池,把不再使用的连接归还给空闲连接池
* 最后判断到底有没有得到连接
* 如果没有得到连接,则再次遍历空闲连接池
*/
public synchronized Connection getFreeConnection() throws SQLException {
Connection conn = null;
Iterator iter = connFactory.freeConnPool.iterator();// 获取空闲连接
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {// 找到未用连接
conn = _conn.getFreeConnection();
_conn.setIsFree(true);
connFactory.freeConnPool.remove(_conn);// 移出空闲区
connFactory.connPool.add(_conn);// 加入连接池
break;
}
}
// 检查空闲池是否为空
if (connFactory.freeConnPool.isEmpty()) {
// 再检查是否能够分配
if (connFactory.current_conn_count < connFactory.maxConnCount) {
int newcount = 0;
// 取得要建立的数目
if (connFactory.maxConnCount - connFactory.current_conn_count >= connFactory.minConnCount) {
newcount = connFactory.minConnCount;
} else {
newcount = connFactory.maxConnCount
- connFactory.current_conn_count;
}
for (int i = 0; i < newcount; i++) {// 创建连接
_Connection _conn = _Connection.getConnection(connFactory);
connFactory.freeConnPool.add(_conn);
connFactory.current_conn_count++;
}
} else {// 如果不能新建,检查是否有已经归还的连接
iter = connFactory.connPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {
conn = _conn.getFreeConnection();
_conn.setIsFree(false);
connFactory.connPool.remove(_conn);
connFactory.freeConnPool.add(_conn);
break;
}
}
}
}
// 再次检查是否能分配连接
if (conn == null) {
iter = connFactory.freeConnPool.iterator();
while (iter.hasNext()) {
_Connection _conn = (_Connection) iter.next();
if (!_conn.isFree()) {
conn = _conn.getFreeConnection();
_conn.setIsFree(true);
connFactory.freeConnPool.remove(_conn);
connFactory.connPool.add(_conn);
break;
}
}
if (conn == null)// 如果不能则说明无连接可用
throw new SQLException("没有可用的数据库连接");
}
System.out.println("get connection");
return conn;
}
// 关闭该连接池中的所有数据库连接
public synchronized void close() throws SQLException {
this.isflag = false;
SQLException excp = null;
// 关闭空闲池
Iterator iter = connFactory.freeConnPool.iterator();
while (iter.hasNext()) {
try {
((_Connection) iter.next()).close();
System.out.println("close connection:free");
connFactory.current_conn_count--;
} catch (Exception e) {
if (e instanceof SQLException)
excp = (SQLException) e;
}
}
// 关闭在使用的连接池
iter = connFactory.connPool.iterator();
while (iter.hasNext()) {
try {
((_Connection) iter.next()).close();
System.out.println("close connection:inused");
connFactory.current_conn_count--;
} catch (Exception e) {
if (e instanceof SQLException)
excp = (SQLException) e;
}
}
if (excp != null)
throw excp;
}
}

 

数据连接代理类_Connection

 

写道
package myConnPool;

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 isFree = false;// 数据库的忙状态
long lastAccessTime = 0;// 最后一次访问时间
// 定义要接管的函数的名字
String CREATESTATE = "createStatement";
String CLOSE = "close";
String PREPARESTATEMENT = "prepareStatement";
private _Connection() {
try {// 创建连接
Class.forName(ConnectionParam.getInstance().getDriver())
.newInstance();
conn = DriverManager.getConnection(ConnectionParam.getInstance()
.getUrl(), ConnectionParam.getInstance().getUser(),
ConnectionParam.getInstance().getPassword());
DatabaseMetaData dm = null;
dm = conn.getMetaData();
} catch (Exception e) {
e.printStackTrace();
}
}
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;
}
obj = method.invoke(conn, args);
// 设置最后一次访问时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
return obj;
}
// 创建连接的工厂,只能让工厂调用
static public _Connection getConnection(ConnectionFactory factory) {
if (factory.isCreate()) {// 判断是否正确初始化的工厂
_Connection _conn = new _Connection();
return _conn;
} else
return null;
}
public Connection getFreeConnection() {
// 返回数据库连接conn的接管类,以便截住close方法
Connection conn2 = (Connection) Proxy.newProxyInstance(conn.getClass()
.getClassLoader(), conn.getClass().getInterfaces(), this);
return conn2;
}

// 该方法真正的关闭了数据库的连接

void close() throws SQLException {
// 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
conn.close();
}

public void setIsFree(boolean value) {
isFree = value;
}

public boolean isFree() {
return isFree;
}
}

 

连接参数类 ConnectionParam

 

写道
package myConnPool;

import java.io.Serializable;

public class ConnectionParam implements Serializable {
private static ConnectionParam connParam=null;
private String driver; // 数据库驱动程序
private String url; // 数据连接的URL
private String user; // 数据库用户名
private String password; // 数据库密码
private int MaxConnectionCount = 4;// 最大连接数
private int MinConnectionCount = 2;// 最小连接数
private ConnectionParam(){}
public static ConnectionParam getInstance(){
if(connParam==null){
connParam=new ConnectionParam();
}
return connParam;
}
public String getDriver() {
return driver;
}
public String getPassword() {
return password;
}
public String getUrl() {
return url;
}
public String getUser() {
return user;
}
public int getMaxConn() {
return this.MaxConnectionCount;
}
public int getMinConn() {
return this.MinConnectionCount;
}
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;
}
public void setMaxConn(int value) {
this.MaxConnectionCount = value;
}
public void setMinConn(int value) {
this.MinConnectionCount = value;
}
}

 

测试类

 

package myConnPool;

import java.sql.*;

public class testmypool {
	
	public static void main(String[] args) {
		
		String user = "root";
		String password = "root";
		String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost/authorization";
		ConnectionParam param = ConnectionParam.getInstance();
		param.setDriver(driver);
		param.setUrl(url);
		param.setUser(user);
		param.setPassword(password);
		param.setMaxConn(4);
		param.setMinConn(2);
		ConnectionFactory cf = null;
		try {
			cf = new ConnectionFactory(param);
			ConnectionFactory cf1 = new ConnectionFactory(param);
			Connection conn1 = null;
			long time = System.currentTimeMillis();
			for (int i = 0; i < 10; i++) {
				conn1 = cf.getFreeConnection();
				Statement stmt = conn1.createStatement();
				ResultSet rs = stmt.executeQuery("select * from function");
				if (rs.next()) {
					System.out.println("conn1 y");
				} else {
					System.out.println("conn1 n");
				}
				conn1.close();
			}
			System.out.println("pool:" + (System.currentTimeMillis() - time));
			time = System.currentTimeMillis();
			Class.forName(param.getDriver()).newInstance();
			for (int i = 0; i < 10; i++) {
				conn1 = DriverManager.getConnection(param.getUrl(), param
						.getUser(), param.getPassword());
				Statement stmt = conn1.createStatement();
				ResultSet rs = stmt.executeQuery("select * from function");
				if (rs.next()) {
					System.out.println("conn1 y");
				} else {
					System.out.println("conn1 n");
				}
				conn1.close();
			}
			System.out
					.println("no pool:" + (System.currentTimeMillis() - time));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				cf.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics