import java.sql.*;
import java.lang.reflect.*;
import org.omg.CORBA.portable.InvokeHandler;
import freemarker.template.utility.ObjectConstructor;
/**
* 定义数据库连接的代理类
*
* @author mark
*
*/
public class ConnectionProxy 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 = "rollbakc";
/**
* 构造函数,采用私有,防止被直接创建
*
* @param param
* 连接参数
*/
private ConnectionProxy(ConnectionParam param) {
// 记录日志
try {
// 创建连接
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin: @10.8.1.234:1521:WF4PPDB","PP42", "PP42");
DatabaseMetaData dm = null;
dm = conn.getMetaData();
// 判断是否支持事务
supportTransaction = dm.supportsTransactions();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
// 判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if (CLOSE.equals(method.getName())) {
// 设置不使用标志
setFree(false);
if (statRef != null)
statRef.close();
if (preStatRef != null)
preStatRef.close();
return null;
}
// 判断是使用了createStatement语句
if (CREATESTATE.equals(method.getName())) {
try {
obj = method.invoke(conn, args);
statRef = (Statement) obj;
return obj;
} catch (ClassCastException ex) {
ex.printStackTrace();
}
}
// 判断是使用了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 ConnectionProxy getConnection(ConnectionFactory factory,
ConnectionParam param) {
// 判断是否正确初始化的工厂
if (factory.isCreate()) {
ConnectionProxy _conn = new ConnectionProxy(param);
return _conn;
} else {
return null;
}
}
public Connection getFreeConnection() {
// 返回数据库连接conn的接管类,以便截住close方法
Connection cn = (Connection) Proxy.newProxyInstance(conn.getClass()
.getClassLoader(), conn.getClass().getInterfaces(), this);
return cn;
}
/**
* 该方法真正的关闭了数据库的连接
*
* @throws SQLException
*/
public void close() throws SQLException {
// 由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接
conn.close();
}
public void setFree(boolean isFree) {
this.isFree = isFree;
}
public boolean isFree() {
return isFree;
}
/**
* 判断是否支持事务
*
* @return boolean
*/
public boolean isSupportTransaction() {
return supportTransaction;
}
}
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
public class ConnectionFactory {
private static ConnectionFactory m_instance = null;
// 在使用的连接池
private LinkedHashSet ConnectionPool = null;
// 空闲连接池
private LinkedHashSet FreeConnectionPool = null;
// 最大连接数
private int MaxConnectionCount = 10;
// 最小连接数S
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();
FreeConnectionPool = new LinkedHashSet();
}
/**
* 使用指定的参数创建一个连接池
*
* @throws SQLException
*/
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) {
// 参数定制
m_instance = new ConnectionFactory();
connparam = param;
m_instance.MaxConnectionCount = fparam
.getMaxConnectionCount();
m_instance.MinConnectionCount = fparam
.getMinConnectionCount();
m_instance.ManageType = fparam.getManageType();
m_instance.isflag = true;
// 初始化,创建MinConnectionCount个连接
System.out.println("connection factory 创建!");
try {
for (int i = 0; i < m_instance.MinConnectionCount; i++) {
ConnectionProxy conn = ConnectionProxy
.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 ex) {
ex.printStackTrace();
}
// 根据策略判断是否需要查询
if (m_instance.ManageType != 0) {
Thread t = new Thread(new FactoryManageThread(
m_instance));
t.start();
}
}
}
}
}
/**
* 标志工厂是否已经创建
*
* @return boolean
*/
public boolean isCreate() {
return m_instance.isflag;
}
/**
* 从连接池中取一个空闲的连接
*
* @return Connection
* @throws SQLException
*/
public synchronized Connection getFreeConnection() throws SQLException {
Connection cn = null;
// 获取空闲连接
Iterator ir = m_instance.FreeConnectionPool.iterator();
while (ir.hasNext()) {
ConnectionProxy conn = (ConnectionProxy) ir.next();
// 找到未用的连接
if (!conn.isFree()) {
cn = conn.getFreeConnection();
conn.setFree(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++) {
ConnectionProxy _conn = ConnectionProxy.getConnection(
m_instance, connparam);
m_instance.FreeConnectionPool.add(_conn);
m_instance.current_conn_count++;
}
} else {
// 如果不能新建,检查是否有已经归还的连接
ir = m_instance.ConnectionPool.iterator();
while (ir.hasNext()) {
ConnectionProxy _conn = (ConnectionProxy) ir.next();
if (!_conn.isFree()) {
cn = _conn.getFreeConnection();
_conn.setFree(false);
m_instance.ConnectionPool.remove(_conn);
m_instance.FreeConnectionPool.add(_conn);
break;
}
}
}
}
// 再次检查是否能分配连接
if (cn == null) {
ir = m_instance.FreeConnectionPool.iterator();
while (ir.hasNext()) {
ConnectionProxy _conn = (ConnectionProxy) ir.next();
if (!_conn.isFree()) {
cn = _conn.getFreeConnection();
_conn.setFree(true);
m_instance.FreeConnectionPool.remove(_conn);
m_instance.ConnectionPool.add(_conn);
break;
}
}
if (cn == null)
// 如果不能则说明无连接可用
throw new SQLException("没有可用的数据库连接");
}
System.out.println("Get Connection");
return cn;
}
/**
* 关闭该连接池中的所有数据库连接
*
* @throws SQLException
*/
public synchronized void close() throws SQLException {
this.isflag = false;
SQLException sqlError = null;
// 关闭空闲池
Iterator ir = m_instance.FreeConnectionPool.iterator();
while (ir.hasNext()) {
try {
((ConnectionProxy) ir.next()).close();
System.out.println("Close connection:Free");
m_instance.current_conn_count--;
} catch (Exception ex) {
if (ex instanceof SQLException) {
sqlError = (SQLException) ex;
}
}
}
// 关闭在使用的连接池
ir = m_instance.ConnectionPool.iterator();
while (ir.hasNext()) {
try {
((ConnectionProxy) ir.next()).close();
System.out.println("Close connection:Using");
} catch (Exception ex) {
if (ex instanceof SQLException) {
sqlError = (SQLException) ex;
}
}
}
if (sqlError != null)
throw sqlError;
}
/**
* 返回是否支持事务
*
* @return boolean
*/
public boolean isSupportTransaction() {
return m_instance.supportTransaction;
}
/**
* 连接池调度管理
*
*/
public void schedule() {
Connection cn = null;
// 再检查是否能够分配
Iterator ir = null;
// 检查是否有已经归还的连接
ir = m_instance.ConnectionPool.iterator();
while (ir.hasNext()) {
ConnectionProxy _conn = (ConnectionProxy) ir.next();
if (!_conn.isFree()) {
cn = _conn.getFreeConnection();
_conn.setFree(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++) {
ConnectionProxy _conn = ConnectionProxy.getConnection(
m_instance, connparam);
m_instance.FreeConnectionPool.add(_conn);
m_instance.current_conn_count++;
}
}
}
}
import java.io.Serializable;
import com.mark.human.model.*;
/**
* 实现数据库连接的参数类
*
* @author mark
*
*/
public class ConnectionParam implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String driver; // 数据库驱动程序
private String url; // 数据连接的URL
private String user; // 数据库用户名
private String password; // 数据库密码
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public ConnectionParam(String driver, String url, String user,
String password) {
this.driver = driver;
this.url = url;
this.user = user;
this.password = password;
}
/**
* @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;
}
}
/**
* 连接池调度线程
*
* @author mark
*
*/
public class FactoryManageThread implements Runnable {
ConnectionFactory cf = null;
long delay = 1000;
public FactoryManageThread(ConnectionFactory obj) {
cf = obj;
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
while (true) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run.....run.....");
// 判断是否已经关闭了工厂,那就退出监听
if (cf.isCreate())
cf.schedule();
else
System.exit(1);
}
}
}
/**
* 连接池工厂参数
*
* @author mark
*
*/
public class FactoryParam {
// 最大连接数
private int MaxConnectionCount = 4;
// 最小连接数
private int MinConnectionCount = 2;
// 回收策略
private int ManageType = 0;
public FactoryParam() {
}
/**
* 构造连接池工厂参数的对象
*
* @param max
* 最大连接数
* @param min
* 最小连接数
* @param type
* 管理策略
*/
public FactoryParam(int max, int min, int type) {
this.MaxConnectionCount = max;
this.MinConnectionCount = min;
this.ManageType = type;
}
public int getManageType() {
return ManageType;
}
public void setManageType(int manageType) {
ManageType = manageType;
}
public int getMaxConnectionCount() {
return MaxConnectionCount;
}
public void setMaxConnectionCount(int maxConnectionCount) {
MaxConnectionCount = maxConnectionCount;
}
public int getMinConnectionCount() {
return MinConnectionCount;
}
public void setMinConnectionCount(int minConnectionCount) {
MinConnectionCount = minConnectionCount;
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class testPool {
public void test1() {
String user = "ppuser";
String password = "ppuser";
String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
String driver = "oracle.jdbc.driver.OracleDriver";
ConnectionParam param = new ConnectionParam(driver, url, user, password);
ConnectionFactory cf = null;
// new ConnectionFactory(param,new FactoryParam());
try {
cf = new ConnectionFactory(param, new FactoryParam());
Connection conn1 = cf.getFreeConnection();
Connection conn2 = cf.getFreeConnection();
Connection conn3 = cf.getFreeConnection();
Statement stmt = conn1.createStatement();
ResultSet rs = stmt.executeQuery("select * from ADMINISTRATION");
if (rs.next()) {
System.out.println("conn1 y");
} else {
System.out.println("conn1 n");
}
stmt.close();
conn1.close();
Connection conn4 = cf.getFreeConnection();
Connection conn5 = cf.getFreeConnection();
stmt = conn5.createStatement();
rs = stmt.executeQuery("select * from ADMINISTRATION");
if (rs.next()) {
System.out.println("conn5 y");
} else {
System.out.println("conn5 n");
}
conn2.close();
conn3.close();
conn4.close();
conn5.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
cf.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
String user = "ppuser";
String password = "ppuser";
String url = "jdbc:oracle:thin:@192.168.0.1:1521:PPDATA";
String driver = "oracle.jdbc.driver.OracleDriver";
ConnectionParam param = new ConnectionParam(driver, url, user, password);
System.out.println("-------" + param.getDriver());
ConnectionFactory cf = null;
try {
cf = new ConnectionFactory(param, new FactoryParam());
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 actioncode");
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 actioncode");
if (rs.next()) {
System.out.println("conn1 y");
System.out.println(rs.getString(1));
System.out.println(rs.getString(2));
} 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();
}
}
}
}
JDBC 连接池代码
最新推荐文章于 2022-11-08 11:45:00 发布