现在的位置: 首页 > 综合 > 正文

JDBC 连接池代码

2013年01月02日 ⁄ 综合 ⁄ 共 15126字 ⁄ 字号 评论关闭

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();
   }
  }
 }

}

 

 

抱歉!评论已关闭.