3.2 数据库连接池 例2: package shop; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; /* java数据库连接池实现 作用: 在数据库存取中,数据库连接池是不可缺少的,它可以提高连接利用率 减少连接等待,对于提高数据存储性能会有不小的作用. 原理: 连接池相当于连接的集合,在连接池初始化时先实例化一定数量的空闲连接 等待用户使用,用户使用完连接再将其返回连接池,这样就免去了最耗时的 创建连接的开销在没有空闲连接的情况下,连接池将自动生成连接再分配给 用户请求. 实例: */ /* * 我的数据库连接池 * * **********模块说明************** * * getInstance()返回POOL唯一实例,第一次调用时将执行构造函数 * 构造函数Pool()调用驱动装载loadDrivers()函数;连接池创建createPool()函数 loadDrivers()装载驱动 * createPool()建连接池 getConnection()返回一个连接实例 getConnection(long time)添加时间限制 * freeConnection(Connection con)将con连接实例返回到连接池 getnum()返回空闲连接数 * getnumActive()返回当前使用的连接数 * */ public class Pool { private static 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;// 连接池实例变量 // 将构造函数私有,不允许外界访问 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 static synchronized Pool getInstance() { if (instance == null) { instance = new Pool(); } return instance; } // 获得一个可用的连接,如果没有则创建一个连接,且小于最大连接限制 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()); } } } package shop; //数据池文件 import java.sql.*; import java.util.*; import java.util.Date; public class DBConnectionPool { private int checkedOut; private Vector<Connection> freeConnections = new Vector<Connection>(); 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(); } // 创建一个新连接 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; } // 获取一个可用连接 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; } }