package connection; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Enumeration; import java.util.Vector; import com.mysql.jdbc.Driver; public class ConnectionPool { private String jdbcDriver=""; //驅動 private String dbURL=""; //鏈接數據庫的URL private String userName=""; //用戶名 private String passWord=""; //密碼 private String testTable=""; //測試表名稱 private int initalConNum=1; //鏈接池的初始大小 private int increatmentalConNum=5; //自動增加的數量 private int maxCon=20; //鏈接池最大的大小 private Vector<PooledConnection> connections=null; //存放鏈接池中連接數據庫的向量 /* * 構造函數 * @param jdbcDriver 驅動 * @param dbURL 鏈接 * @param username * @param password */ public ConnectionPool(String jdbcDriver,String dbURL,String username,String password){ this.jdbcDriver=jdbcDriver; this.dbURL=dbURL; this.userName=username; this.passWord=password; try { createPool(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //返回鏈接池的初始大小 public int getInitialCons(){ return this.initalConNum; } //返回鏈接池的自動增長的大小 public int getIncreatmentalNum(){ return this.increatmentalConNum; } //返回鏈接池中最大的可用鏈接數量 public int getMaxCons(){ return this.maxCon; } //設置最大鏈接數量 public void setMaxCons(int maxCon){ this.maxCon=maxCon; } //獲取測試表的名稱 public String getTestTable(){ return this.testTable; } //設置測試表的名稱 public void setTestTable(String testTable){ this.testTable=testTable; } //建立一個數據庫鏈接池 public synchronized void createPool() throws Exception { //確保鏈接池沒有建立 //若已經建立,則保證其不爲空 if(connections!=null){ return; } //實例化數據庫驅動 Driver driver=(Driver)Class.forName(this.jdbcDriver).newInstance(); //註冊驅動 DriverManager.registerDriver(driver); //建立保存鏈接的向量 this.connections=new Vector<PooledConnection>(); //根據初始化中設置的值來建立鏈接 createConnections(this.initalConNum); } //建立鏈接,numConnections爲要建立的鏈接的數量 private void createConnections(int numConnections){ //循環建立指定數目的鏈接 for(int i=0;i<numConnections;i++){ //maxCon<=0表示鏈接數量沒有上限 //判斷鏈接的數量,若已經達到最大值則推出 if(this.maxCon>0&&this.connections.size()>=this.maxCon) break; //若知足條件則添加一個鏈接到鏈接池中 try { this.connections.addElement(new PooledConnection(newConnection())); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //建立一個新的數據庫鏈接並返回它 private Connection newConnection() throws SQLException{ //建立一個鏈接 Connection conn=DriverManager.getConnection(this.dbURL, this.userName, this.passWord); //若是是第一次建立數據庫,即檢查數據庫,獲取此數據庫容許支持的最大鏈接數目 if(connections.size()==0){ DatabaseMetaData metaData=conn.getMetaData(); int driverMaxConnections=metaData.getMaxConnections(); if(driverMaxConnections>0&&this.maxCon>driverMaxConnections) this.maxCon=driverMaxConnections; } return conn; } // public synchronized PooledConnection getConnection(){ //確保鏈接池已經被建立 if(connections==null) return null; //獲取一個可用的數據庫鏈接 PooledConnection conn=getFreeConnection(); while(conn==null){ //conn==null表示沒有可用的鏈接,表示全部鏈接正在使用當中 wait(250); conn=getFreeConnection(); //從新獲取鏈接,知道獲取爲止 } return conn; } //打印鏈接池中全部鏈接的狀態 public void print(){ System.out.println("total connection:"+this.connections.size()); for(int i=0;i<this.connections.size();i++){ System.out.println(i+":"+this.connections.get(i).isBusy()); } } // private PooledConnection getFreeConnection() { //從鏈接池中獲取一個可用的數據庫鏈接 PooledConnection conn = findFreeConnection(); if(conn==null){ System.out.println("目前數據庫中沒有可用的鏈接,可用建立一些鏈接"); createConnections(this.increatmentalConNum); conn=findFreeConnection(); //若建立以後仍然得不到可用的鏈接,則返回null if(conn==null) return null; } return conn; } private PooledConnection findFreeConnection() { //從全部的鏈接中查找一個可用的鏈接 for(int i=0;i<this.connections.size();i++){ PooledConnection pc=this.connections.elementAt(i); if(!pc.isBusy()){ Connection con=pc.getConnection(); //獲取其鏈接 pc.setBusy(true); //測試此鏈接是否可用,若是不可用則建立一個新的鏈接 try { if(!con.isValid(3000)){ //鏈接不可用則建立一個新的鏈接 try { con=newConnection(); //同時替換掉這個不可用的鏈接對象,若建立失敗則刪除此鏈接同時遍歷下一個鏈接 pc.setConnection(con); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); connections.remove(i--); continue; } } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return pc; //找到一個可用的鏈接,退出循環 } } return null; } //判斷鏈接是否可用 public boolean isValid(Connection con){ try { return con.isValid(3000); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); return false; } } public void returnConnection(Connection conn){ //確保鏈接池存在,若不存在則直接返回 if(connections==null){ return; } PooledConnection pConn=null; Enumeration<PooledConnection> enumerate=connections.elements(); while(enumerate.hasMoreElements()){ pConn=enumerate.nextElement(); //先找到鏈接池中要返回的對象 if(conn==pConn.getConnection()){ pConn.setBusy(false); break; } } } //刷新全部鏈接池的對象 public synchronized void refreshConnections(){ if(connections==null){ System.out.println("鏈接池不存在,不可以刷新!"); return; } PooledConnection pConn=null; Enumeration<PooledConnection> enumerate=connections.elements(); while(enumerate.hasMoreElements()){ pConn=enumerate.nextElement(); while(pConn.isBusy()){ //等待對象結束 wait(1000); } //關閉一個鏈接,用新的鏈接來替代它 closeConnection(pConn.getConnection()); try { pConn.setConnection(newConnection()); pConn.setBusy(false); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //關閉池中全部鏈接並清空鏈接池 public void closeConnectionPool() { if(connections==null){ return; } PooledConnection pConn=null; Enumeration<PooledConnection> enumerate=connections.elements(); while(enumerate.hasMoreElements()){ pConn=enumerate.nextElement(); if(pConn.isBusy()){ //等待對象結束 wait(5000); } //關閉一個鏈接,用新的鏈接來替代它 closeConnection(pConn.getConnection()); //從鏈接池向量中直接刪除它 connections.removeElement(pConn); } //置鏈接池爲空 connections=null; } //關閉一個數據庫鏈接 private void closeConnection(Connection conn){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //使程序等待指定的秒數 private void wait(int seconds){ try { Thread.sleep(seconds); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //內部使用的保存鏈接池對象的類 class PooledConnection{ private Connection connection=null; private boolean isBusy; //構造函數,根據一個Connection構造一個PooledConnection對象 PooledConnection(Connection connection) { this.connection = connection; } //執行查詢操做 public ResultSet executeQuery(String sql) throws SQLException{ return connection.createStatement().executeQuery(sql); } //執行更新操做 public int executeUpdate(String sql) throws SQLException{ return connection.createStatement().executeUpdate(sql); } //返回這個對象中的鏈接 public Connection getConnection(){ return connection; } public void setConnection(Connection con) { // TODO Auto-generated method stub this.connection=con; } public void setBusy(boolean busy) { // TODO Auto-generated method stub this.isBusy=busy; } public boolean isBusy() { // TODO Auto-generated method stub return this.isBusy; } } DBManager類: package com.vl.sql;import java.sql.SQLException; import com.vl.Config;import com.vl.sql.ConnectionPool.PooledConnection;public class DBManager { private static PooledConnection conn; private static ConnectionPool connectionPool; private static DBManager inst; public void close() { try { connectionPool.closeConnectionPool(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public DBManager() { if (inst != null) return; // TODO Auto-generated constructor stub String connStr = String.format("jdbc:mysql://%s:%d/%s", Config.getInstance().mysqlHost, Config.getInstance().mysqlPort,Config.getInstance().mysqlDB); connectionPool = new ConnectionPool("com.mysql.jdbc.Driver", connStr, Config.getInstance().mysqlUser, Config.getInstance().mysqlPassword); try { connectionPool.createPool(); inst = this; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static PooledConnection getConnection() { if (inst == null) new DBManager(); try { conn = connectionPool.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return conn; } public static void main(String[] args) { } } 用法: String sql = "...."; ResultSet rs; PooledConnection conn = null; try { conn = DBManager.getConnection(); rs = conn.executeQuery(sql); if (rs.next()) return rs.getInt(1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { conn.close(); } return 0;