数据库连接池

想必大家对这个应该已经比较熟悉了吧,数据库连接池在数据库连接上起着不可替代的作用,如果你处理的数据十分巨大的话,那就更显重要了,

以下是一个比较简单的连接池实现(复杂连接池可以查看c3p0的源代码)

1.数据库连接信息接口:

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.数据库连接池

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.");   
        } 
    }
}
原文地址:https://www.cnblogs.com/shenliang123/p/3452825.html