Java实现简单的数据库连接池代码详解编程语言

package org.apple.connectionpool; 
 
import java.io.IOException; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.SQLException; 
import java.util.Collections; 
import java.util.Date; 
import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.Properties; 
import java.util.Set; 
import java.util.Timer; 
import java.util.TimerTask; 
import java.util.Vector; 
import java.util.logging.Logger; 
 
public class DbConnectionManager { 
 
    private static DbConnectionManager dbConnectionManager = new DbConnectionManager(); 
    private static Properties properties = new Properties(); 
    private static DbConnectionPool pool = null; 
    static { 
        try { 
            properties.load(DbConnectionManager.class.getResourceAsStream("/org/apple/connectionpool/connectionpoll.properties")); 
            pool = new DbConnectionPool(properties.getProperty("driverClass").trim(), properties.getProperty("url").trim(), properties.getProperty("username").trim(), properties.getProperty("password").trim(), Integer.parseInt(properties.getProperty("minConns").trim()), Integer.parseInt(properties.getProperty("maxConns").trim())); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
    } 
 
    public static DbConnectionManager getInstance() { 
        if (dbConnectionManager != null) { 
            return dbConnectionManager; 
        } else { 
            return new DbConnectionManager(); 
        } 
    } 
 
    public static void main(String[] args) throws SQLException { 
        for (int i = 0; i < 23; i++) { 
            Connection connection = DbConnectionManager.getInstance().getConnection(); 
            System.out.println(connection); 
            DbConnectionManager.getInstance().close(connection); 
        } 
        for (int i = 0; i < 10; i++) { 
            Connection connection = DbConnectionManager.getInstance().getConnection(); 
            System.out.println(connection); 
            DbConnectionManager.getInstance().close(connection); 
        } 
 
    } 
 
    private DbConnectionManager() { 
    } 
 
    public void close(Connection conn) throws SQLException { 
        if (conn != null) { 
            pool.freeConnection(conn); 
        } 
 
    } 
 
    // ----------对外提供的方法---------- 
 
    // ----------对外提供的方法---------- 
    public Connection getConnection() { 
        return pool.getConnection(); 
    } 
 
    public void releaseAll() { 
        pool.releaseAll(); 
    } 
 
} 
 
class DbConnectionPool { 
 
    private final static Logger logger = Logger.getLogger(DbConnectionPool.class.getName()); 
    private static Vector<Connection> freeConnections = new Vector<Connection>(); 
    private static Map<String, ConnectionAndStartTime> busyConnectionsMap = Collections.synchronizedMap(new HashMap<String, ConnectionAndStartTime>()); 
    /** 
     * 计时统计 
     */ 
    private static Timer timer = new Timer(); 
    private static long timerCount = 0; 
    private static int timeOut = 30; 
    static { 
        // 另起一个线程 
        new Thread(new Runnable() { 
            public void run() { 
                timer.schedule(new TimerTask() { 
 
                    @Override 
                    public void run() { 
                        if (LogUtil.isDebug()) { 
                            logger.info("----------[清除超时的线程进行清除...----------"); 
                        } 
                        if (LogUtil.isInfo()) { 
                            System.out.println("----------[清除超时的线程进行清除...----------"); 
                        } 
 
                        timerCount++; 
                        if (timerCount >= 100000000) { 
                            timerCount = 0; 
                        } 
                        if (LogUtil.isDebug()) { 
                            System.out.println("第" + timerCount + "进行定时清除超时的数据库连接"); 
                        } 
                        if (LogUtil.isDebug()) { 
                            System.out.println("----------[清除超时的线程进行清除...----------"); 
                        } 
                        Set<String> set = busyConnectionsMap.keySet(); 
                        Iterator<String> iterator = set.iterator(); 
                        String connectionAndTimeKeyArray = ""; 
                        int index = 0; 
                        while (iterator.hasNext()) { 
                            String connectionClassString = iterator.next(); 
                            ConnectionAndStartTime connectionAndTime = busyConnectionsMap.get(connectionClassString); 
                            if (new Date().getTime() - connectionAndTime.getStartTime() > timeOut * 1000) {// 大于2分钟 
                                if (index == 0) { 
                                    connectionAndTimeKeyArray += connectionClassString; 
                                } else { 
                                    connectionAndTimeKeyArray += "," + connectionClassString; 
                                } 
                                index++; 
                            } 
 
                        } 
                        // 清除 
                        if (connectionAndTimeKeyArray != null && connectionAndTimeKeyArray != "") { 
                            String[] connectionClassStringArray = connectionAndTimeKeyArray.split(","); 
                            for (int i = 0; i < connectionClassStringArray.length; i++) { 
                                if (busyConnectionsMap.get(connectionClassStringArray[i]) != null) { 
                                    System.out.println("connectionClassStringArray[i]" + connectionClassStringArray[i]); 
                                    busyConnectionsMap.remove(connectionClassStringArray[i]); 
                                    if (LogUtil.isDebug()) { 
                                        System.out.println("清除超时的Connection:" + connectionClassStringArray[i]); 
                                    } 
                                    isUsed--; 
                                } 
 
                            } 
                        } 
                        if (LogUtil.isDebug()) { 
                            System.out.println("当前数据库可用连接" + freeConnections.size()); 
                            System.out.println("----------[清除超时的线程进行清除...----------"); 
                            System.out.println("----------[清除超时的线程成功]----------"); 
                        } 
 
                    } 
                    // 30秒后执行定时操作:每个10秒检查是否超时 
                }, 30 * 1000, 10 * 1000); 
 
            } 
        }).start(); 
        if (LogUtil.isInfo()) { 
            System.out.println("超时处理Connection线程启动"); 
        } 
        if (LogUtil.isInfo()) { 
 
        } 
 
    } 
 
    private String driverClass; 
    private String url; 
    private String username; 
    private String password; 
 
    private int minConns = 5; 
    private int maxConns = 20; 
    private static int isUsed = 0; 
    private int timeout = 1000; 
 
    // 构建定时器:自动关闭超时的连接. 
 
    /** 
     * 获取连接 
     */ 
    public static int Try_Time = 0; 
 
    // 只有这个构造方法 
    public DbConnectionPool(String driverClass, String url, String username, String password, int minConns, int maxConns) { 
        this.driverClass = driverClass; 
        this.url = url; 
        this.username = username; 
        this.password = password; 
        this.minConns = minConns; 
        this.maxConns = maxConns; 
        initConnection(); 
    } 
 
    private Connection createNewConnection() { 
 
        try { 
            Connection conn = null; 
            conn = DriverManager.getConnection(url, username, password); 
            if (LogUtil.isInfo()) { 
                logger.info("创建了一个新的链接"); 
            } 
 
            if (conn != null) { 
                return conn; 
            } 
        } catch (SQLException e) { 
            if (LogUtil.isInfo()) { 
                logger.info("获取数据库连接失败" + e); 
            } 
 
        } 
        // 使用连接数有可能数据库已经达到最大的连接 
        return null; 
    } 
 
    /** 
     * 释放连接入连接池 
     */ 
    public synchronized void freeConnection(Connection conn) throws SQLException { 
        if (conn != null && !conn.isClosed()) { 
            freeConnections.add(conn); 
            busyConnectionsMap.remove(conn.toString().trim()); 
            if (isUsed >= 1) { 
                isUsed--; 
            } 
            notifyAll(); 
            if (LogUtil.isInfo()) { 
                logger.info("释放连接!"); 
            } 
 
        } 
 
    } 
 
    public synchronized Connection getConnection() { 
        if (LogUtil.isInfo()) { 
            System.out.println("[系统报告]:已用 " + isUsed + " 个连接,空闲连接个数 " + freeConnections.size()); 
        } 
        // ==========第一种情况 
        if (freeConnections.size() >= 1) { 
            if (LogUtil.isInfo) { 
                System.out.println("[it has free connections]"); 
            } 
 
            Connection conn = freeConnections.firstElement(); 
            try { 
                if (conn.isClosed() || conn == null) { 
                    // 新的连接代替无效连接 
                    conn = createNewConnection(); 
                } 
            } catch (SQLException e) { 
                conn = createNewConnection(); 
            } 
            freeConnections.removeElementAt(0); 
            isUsed++; 
            // 记住内存地址 
            busyConnectionsMap.put(conn.toString().trim(), new ConnectionAndStartTime(conn, new Date().getTime())); 
            return conn; 
        } 
 
        if (freeConnections.size() <= 0) { 
            if (LogUtil.isInfo()) { 
                System.out.println("[now it is getting connection from db]"); 
            } 
 
            // ==========第二种情况.1 
            if (isUsed < maxConns) { 
                Connection conn = createNewConnection(); 
                if (conn != null) { 
                    isUsed++; 
                    busyConnectionsMap.put(conn.toString().trim(), new ConnectionAndStartTime(conn, new Date().getTime())); 
                    return conn; 
                } else { 
                    // 再次自身调用自己:可能已经有空的连接存在 
                    return getConnection(); 
                } 
 
            } 
            // ==========第二种情况.2 
            if (isUsed >= maxConns) { 
                if (LogUtil.isInfo) { 
                    System.out.println("it has no more connections that is allowed for use"); 
                } 
 
                Try_Time++; 
                if (LogUtil.isInfo) { 
                    System.out.println("***[第" + Try_Time + "尝试从新获取连接]***"); 
                } 
 
                if (Try_Time > 10) { 
                    // throw new RuntimeException("***[从新获取数据库连接的失败次数过多]***"); 
                    // 多次不能获得连接则返回null 
                    if (LogUtil.isInfo()) { 
                        System.out.println("重复尝试获取数据库连接10次...???等待解决问题"); 
                    } 
                    return null; 
                } 
                // 连接池已满 
                long startTime = System.currentTimeMillis(); 
                try { 
                    wait(timeout); 
                } catch (InterruptedException e) { 
                    // e.printStackTrace(); 
                } 
                if (new Date().getTime() - startTime > timeout) { 
                    if (LogUtil.isInfo()) { 
                        logger.info("***[没有可获取的链接,正在重试...]***"); 
                    } 
 
                    // 再次自身调用自己 
                    Connection conn = getConnection(); 
                    if (conn != null) { 
                        busyConnectionsMap.put(conn.toString(), new ConnectionAndStartTime(conn, new Date().getTime())); 
                        return conn; 
                    } else { 
                        // 再次自身调用自己 
                        return getConnection(); 
                    } 
                } 
            } 
 
        } 
        return null; 
 
    } 
 
    private synchronized void initConnection() { 
        try { 
            Class.forName(driverClass); // 加载驱动 
            for (int i = 0; i < minConns; i++) { 
                Connection conn = createNewConnection(); 
                if (conn != null) { 
                    freeConnections.add(conn); 
                } else { 
                    throw new RuntimeException("获取的数据库连接为null"); 
                } 
 
            } 
            if (LogUtil.isInfo()) { 
                logger.info("初始化数据库" + minConns + "个连接放入连接池/n"); 
            } 
 
        } catch (ClassNotFoundException e) { 
            if (LogUtil.isInfo()) { 
                logger.info("驱动无法加载,请检查驱动是否存在,driver: " + driverClass + e + "/n"); 
            } 
        } 
    } 
 
    public synchronized void releaseAll() { 
        Enumeration<Connection> enums = freeConnections.elements(); 
        while (enums.hasMoreElements()) { 
            try { 
                enums.nextElement().close(); 
            } catch (SQLException e) { 
                if (LogUtil.isInfo()) { 
                    logger.info("关闭链接失败" + e); 
                } 
 
            } 
        } 
        freeConnections.removeAllElements(); 
        busyConnectionsMap.clear(); 
        if (LogUtil.isInfo()) { 
            logger.info("释放了所有的连接"); 
        } 
 
    } 
 
} 
 
/** 
 *  
 * 记录连接使用的时间 
 *  
 */ 
class ConnectionAndStartTime { 
    private Connection conn; 
 
    private long startTime; 
 
    public ConnectionAndStartTime(Connection conn, long startTime) { 
        super(); 
        this.conn = conn; 
        this.startTime = startTime; 
    } 
 
    public Connection getConn() { 
        return conn; 
    } 
 
    public long getStartTime() { 
        return startTime; 
    } 
 
    public void setConn(Connection conn) { 
        this.conn = conn; 
    } 
 
    public void setStartTime(long startTime) { 
        this.startTime = startTime; 
    } 
} 
 
/** 
 *  
 * 记录日志 
 *  
 */ 
class LogUtil { 
    public static boolean isDebug = true; 
    public static boolean isInfo = true; 
 
    public static boolean isDebug() { 
        return isDebug; 
    } 
 
    public static boolean isInfo() { 
        return isInfo; 
    } 
 
} 
 
/src/org/apple/connectionpool/connectionpoll.properties 
driverClass=oracle.jdbc.driver.OracleDriver 
url=jdbc/:oracle/:thin/:@172.18.2.95/:1521/:MYSQL 
username=wjt 
password=wjt 
minConns=1 
maxConns=3 
 
package com.etc.oa.util; 
 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
 
import org.apple.connectionpool.DbConnectionManager; 
 
public class DBUtil { 
 
    // ================================================== 
    public static Connection getConnection() { 
 
        Connection conn = null; 
        conn = DbConnectionManager.getInstance().getConnection(); 
        //conn = DriverManager.getConnection("jdbc:oracle:thin:@172.18.2.95:1521:MYSQL", "wjt", "wjt"); 
        return conn; 
 
    } 
 
    // ================================================== 
    /** 
     * 建立PreparedStatement实例 
     */ 
    public static PreparedStatement createPreparedStatement(Connection conn, String sql) throws SQLException { 
        try { 
            if (sql != null && conn != null) { 
                PreparedStatement pstmt = conn.prepareStatement(sql); 
                if (pstmt != null) { 
                    return pstmt; 
                } 
            } 
        } catch (SQLException e) { 
            throw e; 
 
        } 
        return null; 
 
    } 
 
    /** 
     * pstmt更新操作 
     */ 
    public static int pstmtExcuteUpdate(PreparedStatement pst) throws SQLException { 
        try { 
            if (pst != null) { 
                return pst.executeUpdate(); 
            } 
        } catch (SQLException e) { 
            throw e; 
 
        } 
        return 0; 
 
    } 
 
    // ================================================== 
 
    // ================================================== 
    /** 
     * pstmt查询操作 
     */ 
    public static ResultSet pstmtExcuteQuery(PreparedStatement pst) throws SQLException { 
        try { 
            if (pst != null) { 
                ResultSet rs = pst.executeQuery(); 
                if (rs != null) { 
                    return rs; 
                } 
            } 
        } catch (SQLException e) { 
            throw e; 
        } 
        return null; 
    } 
 
    // ==================================================== 
 
    // ==================================================== 
    public static void close(Connection conn) throws SQLException { 
        DbConnectionManager.getInstance().close(conn); 
    } 
 
    public static void close(PreparedStatement pst) throws SQLException { 
        if (pst != null) { 
            try { 
                pst.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
    } 
 
    public static void close(ResultSet rs) throws SQLException { 
        if (rs != null) { 
            try { 
                rs.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
    } 
 
    // ========================================================= 
    /** 
     * 快速关闭资源ResultSet rs, PreparedStatement pstmt, Connection conn 
     */ 
    public static void close(ResultSet rs, PreparedStatement pst, Connection conn) throws SQLException { 
        if (rs != null) { 
            try { 
                rs.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
        if (pst != null) { 
            try { 
                pst.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
        if (conn != null) { 
            DbConnectionManager.getInstance().close(conn); 
        } 
 
    } 
 
    /** 
     * 快速关闭资源ResultSet rs, PreparedStatement pstmt 
     */ 
    public static void close(ResultSet rs, PreparedStatement pst) throws SQLException { 
        if (rs != null) { 
            try { 
                rs.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
        if (pst != null) { 
            try { 
                pst.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
 
    } 
 
    /** 
     * 快速关闭资源PreparedStatement pstmt, Connection conn 
     */ 
    public static void close(PreparedStatement pst, Connection conn) throws SQLException { 
        if (pst != null) { 
            try { 
                pst.close(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
        if (conn != null) { 
            DbConnectionManager.getInstance().close(conn); 
        } 
 
    } 
 
    // ========================================================= 
 
    // ========================================================= 
    /** 
     * 事务处理 
     */ 
    public static void rollback(Connection conn) throws SQLException { 
        if (conn != null) { 
            try { 
                conn.rollback(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
    } 
 
    public static void commit(Connection conn) throws SQLException { 
        if (conn != null) { 
            try { 
                conn.commit(); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
    } 
 
    public static void setCommit(Connection conn, Boolean value) throws SQLException { 
        if (conn != null) { 
            try { 
                conn.setAutoCommit(value); 
            } catch (SQLException e) { 
                throw e; 
            } 
        } 
    } 
 
    public static void main(String[] args) throws SQLException { 
        Connection connection4 = DbConnectionManager.getInstance().getConnection(); 
        DbConnectionManager.getInstance().close(connection4); 
        Connection connectiona = DbConnectionManager.getInstance().getConnection(); 
        Connection connectionb = DbConnectionManager.getInstance().getConnection(); 
        Connection connectionc = DbConnectionManager.getInstance().getConnection(); 
        for (int i = 0; i < 10; i++) { 
            Connection connection8 = DbConnectionManager.getInstance().getConnection(); 
            DbConnectionManager.getInstance().close(connection8); 
        } 
 
    } 
} 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/10834.html

(0)
上一篇 2021年7月19日 10:30
下一篇 2021年7月19日 10:30

相关推荐

发表回复

登录后才能评论