重构JDBC数据库连接池
Pool抽象类
package com.sy.day2.t4; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Properties; public abstract class Pool { public String propertiesName = "db.properties"; private static Pool instance = null; //定义唯一实例 protected int maxConnect = 100; //最大链接数 protected int normalConnect; //保持连接数 protected String driverName = null; //驱动字符串 protected Driver driver = null; //驱动变量 //私有构造函数,不允许外界访问 protected Pool() { try { init(); loadDrivers(driverName); } catch (IOException e) { e.printStackTrace(); } } //初始化所有从配置文件读取的成员变量 private void init() throws IOException { InputStream is = Pool.class.getResourceAsStream(propertiesName); Properties p = new Properties(); p.load(is); this.driverName = p.getProperty("db.driver"); this.maxConnect = Integer.parseInt(p.getProperty("db.maxConnect")); this.normalConnect = Integer.parseInt(p.getProperty("db.normalConnect")); } //装载和注册所有JDBC驱动 protected void loadDrivers(String dri){ String driverClassName = dri; try { driver = (Driver) Class.forName(driverClassName).newInstance(); DriverManager.registerDriver(driver); System.out.println("成功注册"+driverClassName); } catch (Exception e) { e.printStackTrace(); } } //创建连接池 public abstract void createPool(); /** * (单例模式)返回数据库连接池 Pool的实例 * @Param driverName 数据库驱动字符串 * @return * @throws IOException * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ public static synchronized Pool getInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException { if(instance != null){ instance = (Pool) Class.forName("com.sy.day2.t4.Pool").newInstance(); } return instance; } //获得一个可用的连接,如果没有就创建一个连接,且小于最大连接限制 public abstract Connection getConnection(); //获得一个可用连接,有时间限制 public abstract Connection getConnection(long time); //将连接对象返回连接池 public abstract void freeConnection(Connection connection); //返回当前空闲连接数 public abstract int getNum(); //返回当前工作的链接数 public abstract int getNumActive(); protected synchronized void release(){ //撤销驱动 try { DriverManager.deregisterDriver(driver); System.out.println("撤销JDBC驱动程序"+driver.getClass().getName()); } catch (SQLException sqlException) { System.out.println("无法撤销JDBC驱动程序注册:"+driver.getClass().getName()); sqlException.printStackTrace(); } } }
DBConnection类数据库连接池
package com.sy.day2.t4; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Date; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; public final class DBConnectionPool extends Pool{ private int checkedOut; //正在使用的链接数 private Vector<Connection> freeConnections = new Vector<>(); //存放产生的连接对象容器 private String passWord = null; //密码 private String url = null; //连接路径 private String userName = null; //用户名 private static int num = 0; //空闲链接数 private static int numActive = 0; //当前可用连接数 private static DBConnectionPool pool = null; //连接池实例变量 protected DBConnectionPool() { try { init(); for (int i = 0; i < normalConnect; i++) { //初始normalConn个连接 Connection c = newConnection(); if(c!=null){ freeConnections.addElement(c); num++; } } } catch (IOException e) { e.printStackTrace(); } } //初始化 private void init() throws IOException { InputStream is = DBConnectionPool.class.getResourceAsStream(propertiesName); Properties p = new Properties(); p.load(is); this.userName = p.getProperty("db.user"); this.passWord = p.getProperty("db.pwd"); this.driverName = p.getProperty("db.driver"); this.url = p.getProperty("db.url"); this.maxConnect = Integer.parseInt(p.getProperty("db.maxConnect")); this.normalConnect = Integer.parseInt(p.getProperty("db.normalConnect")); } private Connection newConnection() { Connection con = null; try { if(userName == null) con= DriverManager.getConnection(url); else con=DriverManager.getConnection(url,userName,passWord); System.out.println("连接池创建一个新的连接"); } catch (SQLException sqlException) { System.out.println("无法创建一个url连接"+url); sqlException.printStackTrace(); return null; } return con; } //产生数据连接池 public static synchronized DBConnectionPool getInstance(){ if(pool==null) pool=new DBConnectionPool(); return pool; } @Override public void createPool() { } //(单例模式)获取一个可用连接 @Override public 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 sqlException) { System.out.println("从连接池中删除一个无效连接"); sqlException.printStackTrace(); } }else if(maxConnect == 0|| checkedOut<maxConnect){ //没有空闲连接且当前连接小于 //最大允许值,最大值为0时,不加限制 con = newConnection(); } if(con!=null){ //当前连接数+1 checkedOut++; } numActive++; return con; } //获取一个连接,并加上等待时间限制(单位为毫秒),超时返回null @Override public Connection getConnection(long timeOut) { long startTime = new Date().getTime(); Connection con = null; while ((con = getConnection())==null){ try { wait(timeOut); } catch (InterruptedException e) { e.printStackTrace(); } if((new Date().getTime()-startTime) >= timeOut) return null; //超时 } return con; } public synchronized void release(){ try { //将连接赋值到美剧中 Enumeration allConnections = freeConnections.elements(); //使用循环关闭所有连接 while (allConnections.hasMoreElements()){ Connection con = (Connection) allConnections.nextElement(); try { con.close(); num--; } catch (SQLException sqlException) { System.out.println("无法关闭连接池中的连接"); sqlException.printStackTrace(); } } freeConnections.removeAllElements(); numActive = 0; }finally { super.release(); } } @Override public synchronized void freeConnection(Connection connection) { freeConnections.add(connection); num++; checkedOut--; numActive--; notifyAll();//解锁 } @Override public int getNum() { return num; } @Override public int getNumActive() { return numActive; } }

浙公网安备 33010602011771号