數據庫鏈接池

想必你們對這個應該已經比較熟悉了吧,數據庫鏈接池在數據庫鏈接上起着不可替代的做用,若是你處理的數據十分巨大的話,那就更顯重要了,java

如下是一個比較簡單的鏈接池實現(複雜鏈接池能夠查看c3p0的源代碼)mysql

1.數據庫鏈接信息接口:sql

package xidian.xidian.sl.dbconnectpool;

/**
 * 數據庫鏈接信息接口
 * 說明:將驅動、鏈接、數據庫名、數據庫密碼等數據鏈接基礎信息作成接口
 * */
public interface IDataBase {
    /**
     * @return 數據庫驅動名   
     * 注意必須加入數據庫驅動包
     * */
    public String getDirver();
    /**
     * @return 數據庫鏈接
     * */
    public String getConnUrl();
    /**
     * @return 數據庫用戶名
     * */
    public String getUserName();
    /**
     * @return 數據庫密碼 
     * */
    public String getPassword();
}

2.數據庫鏈接信息接口實現類數據庫

package xidian.xidian.sl.dbconnectpool;

/**
 * 數據庫鏈接信息接口實現類
 * @author SeDion
 * 該類的默認驅動爲mysql-connector-java 5.0以上版本
 * */
public class Mysql implements IDataBase {

    private String connurl;  
    
    private String userName;  
    
    private String password;     
    
    public Mysql(String connurl,String userName,String password){   
        this.connurl = connurl;   
        this.userName = userName;   
        this.password = password;   
    }     
    
    public Mysql(String serverName,String dbName,String userName,String password){    
        this.connurl = "jdbc:mysql:"+serverName+"/"+dbName;   
        this.userName = userName;   
        this.password = password;  
    }   
    
       
    public String getConnUrl() {   
        // TODO Auto-generated method stub   
        return connurl;   
    }    
       
    public String getDirver() {   
        // TODO Auto-generated method stub   
        return "com.mysql.jdbc.Driver";  
    }    
      
    public String getPassword() {   
        // TODO Auto-generated method stub 
        return password;  
    }   
         
       
    public String getUserName() {   
        // TODO Auto-generated method stub   
        return userName;   
    } 

}

3.數據庫鏈接類安全

package xidian.xidian.sl.dbconnectpool;

import java.sql.Connection;
import java.sql.DriverManager;

/**
 * 數據庫鏈接類
 * 說明:該方法爲單個數據庫的鏈接類,能夠脫離鏈接池來單獨使用
 * */
public class DBConnector {
    private IDataBase db;  
    
    private Connection conn;  
    
    private boolean free = true;    
    
    public DBConnector(IDataBase db) {   
        this.db = db;  
    }    
    /** 
     *  鏈接數據庫
     *  @return 是否鏈接成功  
     */   
    public Connection connect() {   
        try {    
            Class.forName(db.getDirver()).newInstance();     
            conn = DriverManager.getConnection(db.getConnUrl(), db         
                    .getUserName(), db.getPassword());     
            System.out.println("connect success!");   
        } catch (Exception e) {    
            System.out.println("connect failure!");    
            e.printStackTrace();       
            conn = null; 
        }    
        return conn;   
    }    
    public Connection getConnection(){   
        return conn;   
    }    
    /**    
     * 判斷鏈接是否在使用  
     * 注意:在這個地方使用的是包訪問權限,這一項是特意爲鏈接池設置的,對於外面應用 的類並不能讀到此方法。      
     * */   
    boolean isFree() {   
        return free;   
    }    
    /**    
     * 設置鏈接是否空閒   
     * @param isFree   
     * */   
    void setIsFree(boolean isFree) {   
        this.free = isFree;  
    }    
    /**    
     * 關閉數據庫    
     * @return 數據庫是否關閉成功  
     *  */   
    public boolean close() {   
        try {    
            if (conn != null) {     
                conn.close();     
            }     
            return true;    
        } catch (Exception e) {     
            e.printStackTrace();    
            System.err.println("close failure!");
            return false; 
        }   
    }      
     /**    
      * 釋放鏈接,爲鏈接池的重寫提供接口   
      * @return   
      * */   
    boolean release(){   
        throw new RuntimeException("do not use the connection pool,can not release.");   
    }
}

4.數據庫鏈接池ide

package xidian.xidian.sl.dbconnectpool;

import java.util.ArrayList;
import java.util.List;

/**
 * 鏈接池
 * */
public class DBConnectPool {
    private int iniSize = 2;  //鏈接池的初始大小 
    
    private int addSize = 2;  //每次增長的大小   
    
    private int maxSize = 4;  //最大的大小  
    
    private IDataBase db;   
    
    private List<DBConnector> connections = null;  //鏈接池,初始爲空      
    
    public DBConnectPool(IDataBase db){   
        this.db = db;   
        iniPool();   
    }    
    /**   
     * 初始化鏈接池  
     */   
    public void iniPool(){   
        connections = new ArrayList<DBConnector>();  
        connections.addAll(addPool(iniSize));
    }    
    /**     
     * 增長鏈接數 
     * @param size 要增長的數目  
     * @return   
     * */   
    public List<DBConnector> addPool(int size){   
        List<DBConnector> subList = new ArrayList<DBConnector>();   
        for(int i=0; i<size; i++){    
            DBConnector conn = new DBPoolConnector(db);    
            conn.connect();    
            subList.add(conn);    
        }    
        return subList;   
    }    
    /**    
     * 判斷鏈接數是否超過鏈接池的最大鏈接數   
     * @return 是 否   
     * */   
    public boolean isOverRange(){   
        return connections.size() >= maxSize;   
    }    
    /**    
     * 得到空閒鏈接  
     * @return 鏈接   
     * */   
    public DBConnector getConnection(){   
        //循環,有空閒鏈接則進行返回
        for(DBConnector conn : connections){    
            if(conn.isFree()){     
                conn.setIsFree(false);     
                return conn;     
            }    
        }    
        //沒有空閒的
        if(isOverRange()) {    
            throw new RuntimeException("The connection number is over range.");    
        }else{    
            int size = addSize;     
            if((connections.size()+size) > maxSize){
                size = maxSize - connections.size();    
            }
            List<DBConnector> subPool= addPool(size);    
            connections.addAll(subPool);    
            return subPool.get(0);      
        }  
    }  
    /**    
     * 設置鏈接爲空閒狀態  
     * @param conn   
     * */   
    public void freeConnection(DBConnector conn){   
        conn.setIsFree(true);   
    }    
    /**    
     * 釋放全部的空閒鏈接   
     * */   
    public void releaseAllFree(){   
        List<DBConnector> subPool = new ArrayList<DBConnector>();   
        for(DBConnector conn:connections){
            if(conn.isFree()){     
                subPool.add(conn);     
                conn.close();      
            } 
        }
        connections.removeAll(subPool);   
    }    
    /**   
     * 釋放鏈接    
     * @param conn 要釋放的鏈接   
     * */   
    public void release(DBConnector conn){   
        conn.release();    
        connections.remove(conn);   
    }    
    /**    
     * 釋放全部鏈接   
     * */   
    public void release(){   
        for(DBConnector conn:connections)   {    
            conn.release();   
        }    
        connections.removeAll(connections);   
    }     
    /** 
    * 設置初始化最大鏈接數  
    * @param iniSize   
    * */   
    public void setIniSize(int iniSize) {   
        this.iniSize = iniSize;   
    }   
    /**    
     * 設置每次遞增的最大數目   
     * @param addSize   
     * */   
    public void setAddSize(int addSize) {   
        this.addSize = addSize;  
    }   
    /**    
     * 設置鏈接池的最大數目   
     * @param maxSize   
     * */   
    public void setMaxSize(int maxSize) {   
        this.maxSize = maxSize;  
    }     
    /**    
     * 鏈接池內部類,用於管理DBConnector安全性,屏蔽close功能   
     * */   
    class DBPoolConnector extends DBConnector{    
        public DBPoolConnector(IDataBase db) {    
            super(db);     
        }       
        @Override    
        boolean release(){    
            return super.close();   
        }       
        @Override    
        public boolean close(){       
            throw new RuntimeException("Can not close,please use the Connection Pool close this connection.");   
        } 
    }
}
相關文章
相關標籤/搜索