java實現數據庫連接池(連接池的管理用了了享元模式)


package com.bbkj.DbUtils;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * Created by Administrator on 2016/12/7.
 */
public interface IConnectionPool {
    // 獲得連接
    public Connection getConnection();
    // 獲得當前連接
    public Connection getCurrentConnecton();
    // 回收連接
    public void releaseConn(Connection conn) throws SQLException;
    // 銷毀清空
    public void destroy();
    // 連接池是活動狀態
    public boolean isActive();
    // 定時器,檢查連接池
    public void cheackPool();
}

 

package com.bbkj.DbUtils;

import com.bbkj.common.DBbean;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

/**
 * Created by Administrator on 2016/12/7.
 */
public class ConnectionPool implements IConnectionPool {

    //連接池配置屬性
    private DBbean dbBean;
    private boolean isActive =  false;//數據連接獲得狀態
    private int contActive = 0;//記錄創建的總的練級數
    //空閑連接
    private List<Connection> freeConnection = new Vector<Connection>();
    //活動連接
    private List<Connection> activeConnection = new Vector<Connection>();

    //將線程和連接綁定,保證事務能統一執行
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

    public ConnectionPool(DBbean dbBean) {
        super();
        this.dbBean = dbBean;
        init();
        cheackPool();
    }


    // 初始化
    public void init() {
        try {
            Class.forName(dbBean.getDriverName());
            for (int i = 0; i < dbBean.getInitConnections(); i++) {
                Connection conn;
                conn = newConnection();
                // 初始化最小連接數
                if (conn != null) {
                    freeConnection.add(conn);
                    contActive++;
                }
            }
            isActive = true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public synchronized  Connection getConnection() {
        Connection conn = null;
        try {
            // 判斷是否超過最大連接數限制
            if(contActive < this.dbBean.getMaxActiveConnections()){
                if (freeConnection.size() > 0) {
                    conn = freeConnection.get(0);
                    if (conn != null) {
                        threadLocal.set(conn);
                    }
                    freeConnection.remove(0);
                } else {
                    conn = newConnection();
                }

            }else{
                // 繼續獲得連接,直到從新獲得連接
                wait(this.dbBean.getConnTimeOut());
                conn = getConnection();
            }
            if (isValid(conn)) {
                activeConnection.add(conn);
                contActive ++;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public Connection getCurrentConnecton() {
        // 默認線程里面取
        Connection conn = threadLocal.get();
        if(!isValid(conn)){
            conn = getConnection();
        }
        return conn;
    }

    // 獲得新連接
    private synchronized Connection newConnection()
            throws ClassNotFoundException, SQLException {
        Connection conn = null;
        if (dbBean != null) {
            Class.forName(dbBean.getDriverName());
            conn = DriverManager.getConnection(dbBean.getUrl(),
                    dbBean.getUserName(), dbBean.getPassword());
        }
        return conn;
    }

    // 釋放連接
    public synchronized  void releaseConn(Connection conn) throws SQLException {
        if (isValid(conn)&& !(freeConnection.size() > dbBean.getMaxConnections())) {
            freeConnection.add(conn);
            activeConnection.remove(conn);
            contActive --;
            threadLocal.remove();
            // 喚醒所有正待等待的線程,去搶連接
            notifyAll();
        }
    }

    //銷毀連接池
    public synchronized  void destroy() {
        for (Connection conn : freeConnection) {
            try {
                if (isValid(conn)) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        for (Connection conn : activeConnection) {
            try {
                if (isValid(conn)) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        isActive = false;
        contActive = 0;
    }

    // 連接池狀態
    public boolean isActive() {
        return isActive;
    }

    // 判斷連接是否可用
    private boolean isValid(Connection conn) {
        try {
            if (conn == null || conn.isClosed()) {
                return false;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return true;
    }

    // 定時檢查連接池情況
    public void cheackPool() {
        if(dbBean.isCheakPool()){
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    // 1.對線程里面的連接狀態
                    // 2.連接池最小 最大連接數
                    // 3.其他狀態進行檢查,因為這里還需要寫幾個線程管理的類,暫時就不添加了
                    System.out.println("空線池連接數:"+freeConnection.size());
                    System.out.println("活動連接數::"+activeConnection.size());
                    System.out.println("總的連接數:"+contActive);
                }
            },dbBean.getLazyCheck(),dbBean.getPeriodCheck());
        }
    }
}

 

package com.bbkj.DbUtils;

import com.bbkj.common.DBbean;

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

/**
 * Created by Administrator on 2016/12/7.
 */
public class DBInitInfo {
    public  static List<DBbean> beans = null;
    static{
        beans = new ArrayList<DBbean>();
        // 這里數據 可以從xml 等配置文件進行獲取
        // 為了測試,這里我直接寫死
        DBbean beanOracle = new DBbean();
        beanOracle.setDriverName("oracle.jdbc.driver.OracleDriver");
        beanOracle.setUrl("jdbc:oracle:thin:@10.248.2.111:1521:orcl");
        beanOracle.setUserName("etrackchb");
        beanOracle.setPassword("etrackchb");

        beanOracle.setMinConnections(5);
        beanOracle.setMaxConnections(100);

        beanOracle.setPoolName("oraclePool");
        beans.add(beanOracle);
    }
}

 

package com.bbkj.DbUtils;

import com.bbkj.common.DBbean;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;

/**
 * Created by Administrator on 2016/12/7.
 */
public class ConnectionPoolManager {
    // 連接池存放
    public Hashtable<String,IConnectionPool> pools = new Hashtable<String, IConnectionPool>();

    // 初始化
    private ConnectionPoolManager(){
        init();
    }

    // 單例實現
    public static ConnectionPoolManager getInstance(){
        return Singtonle.instance;
    }
    private static class Singtonle {
        private static ConnectionPoolManager instance =  new ConnectionPoolManager();
    }

    // 初始化所有的連接池
    public void init(){
        for(int i =0;i<DBInitInfo.beans.size();i++){
            DBbean bean = DBInitInfo.beans.get(i);
            ConnectionPool pool = new ConnectionPool(bean);
            if(pool != null){
                pools.put(bean.getPoolName(), pool);
                System.out.println("Info:Init connection successed ->" +bean.getPoolName());
            }
        }
    }

    // 獲得連接,根據連接池名字 獲得連接
    public Connection getConnection(String poolName){
        Connection conn = null;
        if(pools.size()>0 && pools.containsKey(poolName)){
            conn = getPool(poolName).getConnection();
        }else{
            System.out.println("Error:Can't find this connecion pool ->"+poolName);
        }
        return conn;
    }

    // 關閉,回收連接
    public void close(String poolName,Connection conn){
        IConnectionPool pool = getPool(poolName);
        try {
            if(pool != null){
                pool.releaseConn(conn);
            }
        } catch (SQLException e) {
            System.out.println("連接池已經銷毀");
            e.printStackTrace();
        }
    }

    // 清空連接池
    public void destroy(String poolName){
        IConnectionPool pool = getPool(poolName);
        if(pool != null){
            pool.destroy();
        }
    }

    // 獲得連接池
    public IConnectionPool getPool(String poolName){
        IConnectionPool pool = null;
        if(pools.size() > 0){
            pool = pools.get(poolName);
        }
        return pool;
    }



}

使用 ConnectionPoolManager 即可調用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM