`
toking79
  • 浏览: 23025 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java实现数据库连接池

 
阅读更多

 本文利用JAVA代码,自行设计数据库连接池.

package scut.ailab.connectionpool;
import java.lang.reflect.*;
import java.sql.*;
/**
 * @author youyongming
 * 定义数据库连接的代理类
 */
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 连接
  */
 static public _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;
 } 
}

ConnectionFactory.java

package scut.ailab.connectionpool;
/**
 * @author youyongming
 *
 */
import java.util.LinkedHashSet;
import java.sql.*;
import java.util.Iterator;
public class ConnectionFactory {
 private static ConnectionFactory m_instance = null;
 //在使用的连接池
 private LinkedHashSet ConnectionPool = null;
 //空闲连接池
 private LinkedHashSet 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();
  FreeConnectionPool = new LinkedHashSet();
 }
 
 /**
  * 使用指定的参数创建一个连接池
  */
 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     {
     _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    {
    _Connection _conn = _Connection.getConnection(m_instance, m_instance.connparam);
    m_instance.FreeConnectionPool.add(_conn);
    m_instance.current_conn_count ++;
   }
  }
 }
}

 ConnectionParam.java

 

 

package scut.ailab.connectionpool;
import java.io.Serializable;
/**
 * @author youyongming
 * 实现数据库连接的参数类
 */
public class ConnectionParam implements Serializable {
 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;
 }
}

 

 

FactoryMangeThread.java

/*
 * Created on 2003-5-13
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package scut.ailab.connectionpool;
/**
 * @author youyongming
 *
 */
//连接池调度线程
public class FactoryMangeThread implements Runnable {
 ConnectionFactory cf = null;
 long delay = 1000;
 public FactoryMangeThread(ConnectionFactory obj)
 {
  cf = obj;
 }
 /* (non-Javadoc)
  * @see java.lang.Runnable#run()
  */
 public void run() {
  while(true){
   try{
    Thread.sleep(delay);
   }
   catch(InterruptedException e){}
   System.out.println("eeeee");
   //判断是否已经关闭了工厂,那就退出监听
   if (cf.isCreate())
    cf.schedule();
   else
    System.exit(1);
  }
 }
}

 FactoryParam.java

 

/*
 * Created on 2003-5-13
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package scut.ailab.connectionpool;
/**
 * @author youyongming
 *
 */
//连接池工厂参数
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.ManageType = type;
  this.MaxConnectionCount = max;
  this.MinConnectionCount = min;
 }
 
 /**
  * 设置最大的连接数
  * @param value
  */
 public void setMaxConn(int value)
 {
  this.MaxConnectionCount = value;
 }
 /**
  * 获取最大连接数
  * @return
  */
 public int getMaxConn()
 {
  return this.MaxConnectionCount;
 }
 /**
  * 设置最小连接数
  * @param value
  */
 public void setMinConn(int value)
 {
  this.MinConnectionCount = value;
 }
 /**
  * 获取最小连接数
  * @return
  */
 public int getMinConn()
 {
  return this.MinConnectionCount;
 }
 public int getType()
 {
  return this.ManageType;
 }
}

 

 

testmypool.java

/*
 * Created on 2003-5-13
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package scut.ailab.connectionpool;
/**
 * @author youyongming
 *
 */
import java.sql.*;
public class testmypool {
 public void test1()
 {
  String user = "DevTeam";
  String password = "DevTeam";
  String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
  String url = "jdbc:odbc:gfqh2";
  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 requests");
   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 requests");
   if (rs.next())
   {
    System.out.println("conn5 y");  
   }
   else
   {
    System.out.println("conn5 n");  
   } 
   conn2.close();
   conn3.close();
   conn4.close();
   conn5.close();
   }
  catch(Exception e)
  {
   e.printStackTrace();
  }
  finally{
   try{
    cf.close();
   }
   catch(Exception e)
   {
    e.printStackTrace();
   }
  } 
 }
 public static void main(String[] args) {
  String user = "DevTeam";
  String password = "DevTeam";
  String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
  String url = "jdbc:odbc:gfqh2";
  ConnectionParam param = new ConnectionParam(driver,url,user,password);
  ConnectionFactory cf = null;//new ConnectionFactory(param,new FactoryParam());
  try{
   cf = new ConnectionFactory(param,new FactoryParam());
   ConnectionFactory cf1= 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 requests");
    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 requests");
    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();
   }
  }
 }
}

 

 

分享到:
评论

相关推荐

    Java jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java 语言中,JDBC(Java DataBase Connection)是应用程序与数据库沟通的桥梁。在 Web 应用开发的早期,主要使用的技术是 CGIASPPHP 等。之后,Sun 公司推出了基于 Java 语言的 ...

    Java实现数据库连接池..docx

    Java 实现数据库连接池主要涉及两个关键点:减少使用者与连接池之间的耦合度和接管 `Connection.close()` 方法。为了实现这两个目标,我们可以利用 Java 的动态代理机制。 首先,了解数据库连接池的作用。连接池是...

    JAVA实现数据库连接池代码

    基于JAVA语言的一种有效的数据库连接池的实现代码。

    JAVA 使用数据库连接池连接Oracle数据库全代码

    ### JAVA 使用数据库连接池连接Oracle数据库全代码解析 #### 一、概述 本文将详细介绍如何在Java项目中使用Apache DBCP(Database Connection Pool)来连接Oracle数据库,并提供完整的示例代码。通过这种方式,我们...

    Java实现数据库连接池..pdf

    在本主题中,我们将探讨如何使用Java的动态代理技术来实现一个更灵活、耦合度更低的数据库连接池。 首先,让我们了解动态代理的工作原理。在Java中,动态代理允许我们在运行时创建一个实现了指定接口的新类。这个新...

    ConnectionPool 基于java实现数据库连接池

    在Java中,数据库连接池通常通过第三方库如Apache的DBCP、C3P0或HikariCP来实现。然而,为了学习目的,我们可以自己模拟一个简单的连接池。这个项目的核心概念包括: 1. **连接创建与管理**:在应用启动时,连接池...

    Java实现数据库连接池简易教程

    本文将介绍一个简单的数据库连接池实现,包括设计思路和关键类的讲解。 首先,我们来看一下数据库连接池的核心类: 1. **ConnectionParam**:这是一个配置类,用于存储数据库连接的相关参数,如驱动名(driver)、...

    java_jdbc数据库连接池总结

    Java JDBC 数据库连接池总结 Java JDBC 数据库连接池是 Java 应用程序访问数据库的基本原理之一。Java 语言通过 JDBC 技术访问数据库,JDBC 是一种“开放”的方案,为数据库应用开发人员和数据库前台工具开发人员...

    JAVA 完整的数据库连接池实现

    总结,Java 完整的数据库连接池实现涉及到选择合适的连接池实现、配置参数、初始化连接池以及在代码中正确地获取和释放连接。理解这些概念和步骤对于优化 Java 应用程序的数据库性能至关重要。通过合理配置和使用...

    java手写数据库连接池

    在实际开发中,虽然手写数据库连接池可以加深对数据库连接池原理的理解,但更常见的情况是使用成熟的连接池实现,如C3P0、Apache DBCP、HikariCP等,它们经过大量优化,提供了更好的性能和稳定性。 总的来说,理解...

    Java各数据库连接池配置介绍

    在Java中,有多种数据库连接池实现,包括C3P0、DBCP和Proxool等。 **C3P0连接池配置参数详解** 1. `acquireIncrement`:当连接池中的连接耗尽时,一次同时尝试获取的连接数。默认值为3,意味着如果连接池为空,它...

    java数据库连接池

    描述:本篇将详细介绍Java数据库连接池的概念,代码实现以及其在实际项目中的应用。数据库连接池是Java开发中优化数据库访问效率的关键技术,通过复用预创建的数据库连接,避免频繁创建和销毁连接带来的性能开销。 ...

    使用JAVA中的动态代理实现数据库连接池

    在本文中,我们将探讨如何使用Java的动态代理来实现数据库连接池,从而解决传统连接池设计中的耦合度问题和资源管理问题。 首先,数据库连接池是应用程序管理数据库连接的一种高效方式。它通过复用已建立的数据库...

    数据库连接池的一个简单实现

    在Java中,常见的数据库连接池实现有C3P0、Apache DBCP、HikariCP等。本文将介绍一个简单的自定义数据库连接池实现,主要涉及以下几个核心组件: 1. **连接池配置**:定义连接池的大小、超时时间、数据库连接参数...

    JAVA数据库连接池

    Java数据库连接池是Java开发中一个非常重要的技术,它主要用于管理数据库连接,提高数据库操作的效率和性能。在Java应用程序中,频繁地创建和关闭数据库连接会导致大量的系统资源浪费,而连接池则可以复用已建立的...

    java写的数据库连接池

    本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池是管理数据库连接的一种机制,它允许应用程序重复使用已建立的数据库连接,而不是每次需要时都创建新的...

Global site tag (gtag.js) - Google Analytics