java数据库连接池

来源:互联网 发布:linux 看文件最后几行 编辑:程序博客网 时间:2024/06/05 19:05
作用:

数据库存取中,数据库连接池是不可缺少的,它可以提高连接利用率

减少连接等待,对于提高数据存储性能会有不小的作用.

原理:

连接池相当于连接的集合,在连接池初始化时先实例化一定数量的空闲连接

等待用户使用,用户使用完连接再将其返回连接池,这样就免去了最耗时的

创建连接的开销在没有空闲连接的情况下,连接池将自动生成连接再分配给

用户请求.

 

实例:

package shop.DbPool;

/*
 我的数据库连接池

  ***********模块说明**************

 getInstance()返回POOL唯一实例,第一次调用时将执行构造函数
 构造函数Pool()调用驱动装载loadDrivers()函数;连接池创建createPool()函数
 loadDrivers()装载驱动
 createPool()建连接池
 getConnection()返回一个连接实例
 getConnection(long time)添加时间限制
 freeConnection(Connection con)将con连接实例返回到连接池
 getnum()返回空闲连接数
 getnumActive()返回当前使用的连接数

 */

import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;

public class Pool {

  static private Pool instance = null; //定义唯一实例

  private int maxConnect = 100;//最大连接数
  private int normalConnect = 10;//保持连接数
  private String password = "";//密码
  private String url = "jdbc:mysql://localhost/shop";//连接URL
  private String user = "root";//用户名
  private String driverName = "com.mysql.jdbc.Driver";//驱动类
  Driver driver = null;//驱动变量
  DBConnectionPool pool = null;//连接池实例变量

  //返回唯一实例
  static synchronized public Pool getInstance() {
    if (instance == null) {
      instance = new Pool();
    }

    return instance;
  }

  //将构造函数私有,不允许外界访问
  private Pool() {
    loadDrivers(driverName);
    createPool();

  }

  //装载和注册所有JDBC驱动程序
  private void loadDrivers(String dri) {

    String driverClassName = dri;
    try {
      driver = (Driver) Class.forName(driverClassName).newInstance();
      DriverManager.registerDriver(driver);
      System.out.println("成功注册JDBC驱动程序" + driverClassName);
    }
    catch (Exception e) {
      System.out.println("无法注册JDBC驱动程序:" + driverClassName + ",错误:" + e);
    }
  }

  //创建连接池
  private void createPool() {
    pool = new DBConnectionPool(password, url, user, normalConnect, maxConnect);
    if (pool != null) {
      System.out.println("创建连接池成功");
    }
    else {
      System.out.println("创建连接池失败");
    }
  }

  //获得一个可用的连接,如果没有则创建一个连接,且小于最大连接限制
  public Connection getConnection() {
    if (pool != null) {
      return pool.getConnection();
    }
    return null;
  }

  //获得一个连接,有时间限制
  public Connection getConnection(long time) {
    if (pool != null) {
      return pool.getConnection(time);
    }
    return null;
  }

  //将连接对象返回给连接池
  public void freeConnection(Connection con) {
    if (pool != null) {
      pool.freeConnection(con);
    }
  }

  //返回当前空闲连接数
  public int getnum()
  {
    return pool.getnum();
  }


  //返回当前连接数
  public int getnumActive()
  {
    return pool.getnumActive();
  }


  //关闭所有连接,撤销驱动注册
  public synchronized void release() {

    ///关闭连接
    pool.release();

    ///撤销驱动
    try {
      DriverManager.deregisterDriver(driver);
      System.out.println("撤销JDBC驱动程序 " + driver.getClass().getName());
    }
    catch (SQLException e) {
      System.out.println("无法撤销JDBC驱动程序的注册:" + driver.getClass().getName());
    }

  }

}

 

 

数据池文件

DBConnectionPool.java

 

package shop.DbPool;


import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;


public class DBConnectionPool {
  private int checkedOut;
  private Vector freeConnections = new Vector();
  private int maxConn;
  private int normalConn;
  private String password;
  private String url;
  private String user;
  private static int num=0;//空闲的连接数
  private static int numActive=0;//当前的连接数

  public DBConnectionPool(String password, String url, String user,
                          int normalConn, int maxConn) {
    this.password = password;
    this.url = url;
    this.user = user;
    this.maxConn = maxConn;
    this.normalConn = normalConn;

    for (int i = 0; i < normalConn; i++) { //初始normalConn个连接
      Connection c = newConnection();
      if (c != null)
        {freeConnections.addElement(c);num++;}
    }
  }

  //释放不用的连接到连接池
  public synchronized void freeConnection(Connection con) {
    freeConnections.addElement(con);
    num++;
    checkedOut--;
    numActive--;
    notifyAll();
  }

  //获取一个可用连接
  public synchronized Connection getConnection() {
    Connection con = null;

    if (freeConnections.size() > 0) { //还有空闲的连接
      num--;

      con = (Connection) freeConnections.firstElement();
      freeConnections.removeElementAt(0);
      try {
        if (con.isClosed()) {
          System.out.println("从连接池删除一个无效连接");
          con = getConnection();
        }
      }
      catch (SQLException e) {
        System.out.println("从连接池删除一个无效连接");
        con = getConnection();
      }
    }

    else if (maxConn == 0 || checkedOut < maxConn) { //没有空闲连接且当前连接小于最大允许值,最大值为0则不限制
      con = newConnection();
    }

    if (con != null) { //当前连接数加1
      checkedOut++;
    }

    numActive++;
    return con;

  }

  //获取一个连接,并加上等待时间限制,时间为毫秒
  public synchronized Connection getConnection(long timeout) {
    long startTime = new Date().getTime();
    Connection con;
    while ( (con = getConnection()) == null) {

      try {
        wait(timeout);
      }
      catch (InterruptedException e) {}

      if ( (new Date().getTime() - startTime) >= timeout) {
        return null; //超时返回
      }
    }
    return con;
  }

  //关闭所有连接
  public synchronized void release() {
    Enumeration allConnections = freeConnections.elements();
    while (allConnections.hasMoreElements()) {
      Connection con = (Connection) allConnections.nextElement();
      try {
        con.close();
        num--;
      }
      catch (SQLException e) {
        System.out.println("无法关闭连接池中的连接");
      }
    }
    freeConnections.removeAllElements();
    numActive=0;
  }

  //创建一个新连接
  private Connection newConnection() {
    Connection con = null;
    try {
      if (user == null) { //用户,密码都为空
        con = DriverManager.getConnection(url);
      }
      else {
        con = DriverManager.getConnection(url, user, password);
      }
      System.out.println("连接池创建一个新的连接");
    }
    catch (SQLException e) {
      System.out.println("无法创建这个URL的连接" + url);
      return null;
    }
    return con;
  }


  //返回当前空闲连接数
  public int getnum()
  {
    return num;
  }


  //返回当前连接数
  public int getnumActive()
  {
    return numActive;
  }