package com.mark.human.db;
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();
}
}
/**
* (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())){
//设置不使用标志
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;
}
}
===================================================================================
package com.mark.human.db;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
/**
*
* @author mark
*
*/
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++;
}
}
}
}
================================================================================
package com.mark.human.db;
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;
}
}
============================================================================
package com.mark.human.db;
/**
* 连接池调度线程
*
* @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);
}
}
}
=================================================================================
package com.mark.human.db;
/**
* 连接池工厂参数
*
* @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;
}
}
============================================================================
package com.mark.human.db;
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();
}
}
}
}