• JDBC数据库连接池的实现


    在网上搜数据库连接池的实现,跳出来一大堆,各式各样的。看到很多评论都说:现在都什么年代了还自己写连接池,现在成熟稳定的连接池有很多,我看到提到最多的是:C3P0;

    确实C3P0用起来感觉不错,很方便,但是还是想自己尝试写写,不能局限于别人实现了,就直接拿来用,就不用思考了,这点很危险!可能自己写的东西没有技术牛人写的效率高,或许bug比较多,但是终究是自己的东西!

    数据库连接池代码:

    package com.hodmct.db;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.Iterator;
    
    import org.apache.log4j.Logger;
    
    import com.hodmct.config.ConfigManager;
    import com.hodmct.config.DataBaseConfig;
    
    /**
     * 数据库连接池
     * 
     * @author quyongjin
     * @2013-4-10 下午02:22:47
     * @version V0.1
     */
    
    public class DBConnectionPool {
    
        private Logger log = Logger.getLogger(DBConnectionPool.class);
    
        /** 使用的连接数 */
        private int inUsed = 0;
    
        /** 新建的连接数 */
        private int newConnNum = 0;
    
        /** 容器,空闲连接 */
        private ArrayList<Connection> freeConnections = new ArrayList<Connection>();
    
        /** 数据库配置类 */
        private DataBaseConfig dataConfig = ConfigManager.dataConfig;
    
        /**
         * 初始化线程池时创建最小数的连接
         */
        public DBConnectionPool() {
            synchronized (this) {
                for (int i = 0; freeConnections.size() < dataConfig
                        .getMinLinkConn(); i++) {
                    Connection con = newConnection(); // 新建连接
                    newConnNum++;
                    freeConnections.add(con);
                }
            }
            log.info("最小连接数创建完毕,现有" + freeConnections.size() + "个连接!");
        }
    
        /**
         * 使用完之后释放连接
         */
        public synchronized void freeConnection(Connection con) {
            // 当con不为空时,调用该方法inUsed才减一
            if (con != null) {
                if (this.freeConnections.size() <= dataConfig.getMinLinkConn()) {
                    // 添加到空闲连接的末尾
                    this.freeConnections.add(con);
                } else {
                    try {
                        con.close();
                        if(con.isClosed()){
                            this.newConnNum--;
                        }
                    } catch (SQLException e) {
                        log.error("数据库连接关闭异常!",e);
                    }
                }
                this.inUsed--;
            }
        }
    
        /**
         * 从连接池里得到连接
         * 
         * @return
         */
        public synchronized Connection getConnection() {
            Connection con = null;
    
            // 数据库连接数大于正在使用的连接数时才能创建新的连接
            if (dataConfig.getMaxLinkConn() > this.inUsed) {
                if (this.freeConnections.size() > 0) {
                    con = (Connection) this.freeConnections.get(0);
                    this.freeConnections.remove(0);// 如果连接分配出去了,就从空闲连接里删除
                } else {
                    if (this.newConnNum < dataConfig.getMaxLinkConn()) {
                        con = newConnection(); // 新建连接
                        if(con != null){
                            this.newConnNum++;
                        }
                    }
                }
                if (con != null) {
                    this.inUsed++;
                    log.info("从数据库连接池中得到连接,现剩余" + freeConnections.size() + "个空闲连接,"
                            + "现在有" + inUsed + "个连接在使用,创建了" + this.newConnNum +"个新连接!");
                }
            } else {
                log.info("数据库连接数已经达到最大连接数,不能获得连接!");
            }
    
            return con;
        }
    
        /**
         * 释放全部连接
         */
        @SuppressWarnings("rawtypes")
        public synchronized void release() {
            synchronized (this) {
                Iterator allConns = this.freeConnections.iterator();
                while (allConns.hasNext()) {
                    Connection con = (Connection) allConns.next();
                    try {
                        con.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                this.freeConnections.clear();
                this.newConnNum = 0;
            }
    
        }
    
        private Connection newConnection() {
            Connection con = null;
            try {
                Class.forName(dataConfig.getDriver());
                con = DriverManager.getConnection(dataConfig.getUrl(),
                        dataConfig.getUser(), dataConfig.getPwd());
            } catch (ClassNotFoundException e) {
                log.error("缺少该数据库连接驱动,sorry!", e);
            } catch (SQLException e1) {
                log.error("不能创建连接,sorry!", e1);
            }
            return con;
        }
    
    }
    数据库配置类DataBaseConfig代码:
    package com.hodmct.config;
    
    /**
     * 链接数据库配置类
     * 
     * @author quyongjin
     * @2013-4-9 下午04:41:55
     * @version V0.1
     */
    
    public class DataBaseConfig {
        
        /** 链接数据库驱动 */
        private String driver;
        
        /** 链接数据库的Url */
        private String url;
        
        /** 链接数据库的用户名 */
        private String user;
        
        /** 链接数据库的密码 */
        private String pwd;
        
        /** 最大连接数 */
        private int maxLinkConn;
        
        /** 最小连接数 */
        private int minLinkConn;
    
        public String getDriver() {
            return driver;
        }
    
        public void setDriver(String driver) {
            this.driver = driver;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        public String getUser() {
            return user;
        }
    
        public void setUser(String user) {
            this.user = user;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    
        public int getMaxLinkConn() {
            return maxLinkConn;
        }
    
        public void setMaxLinkConn(int maxLinkConn) {
            this.maxLinkConn = maxLinkConn;
        }
    
        public int getMinLinkConn() {
            return minLinkConn;
        }
    
        public void setMinLinkConn(int minLinkConn) {
            this.minLinkConn = minLinkConn;
        }
    
    }

    读取数据库配置文件代码:

    package com.hodmct.config;
    
    import java.io.FileInputStream;
    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import com.hodmct.utils.XMLUtils;
    
    /**
     * 读取databases.xml配置文件
     * 
     * @author quyongjin
     * @2013-4-9 下午05:15:24
     * @version V0.1
     */
    
    public class ReadDataBasesConfigXML {
        
        private static Logger log = Logger.getLogger(ReadDataBasesConfigXML.class);
        
        /**
         * 无参的读取配置文件databases.xml方法
         */
        public static void databasesConfigLoad(){
            databasesConfigLoad(System.getProperty("user.dir") + "/config/databases.xml");
        }
    
        /**
         * 指定配置文件databases.xml路径的读取方法
         * @param xmlFilePath databases.xml 路径
         */
        private static void databasesConfigLoad(String xmlFilePath) {
            try {
                Document document = XMLUtils.parse(new FileInputStream(xmlFilePath));
                Element root = document.getRootElement();
                String driver = root.elementText("database-driver");
                if(driver != null && !"".equals(driver)){
                    ConfigManager.dataConfig.setDriver(driver);
                }else{
                    log.info("## 数据库驱动配置为空或读取有误!");
                }
                
                String url = root.elementText("database-url");
                if(url != null && !"".equals(url)){
                    ConfigManager.dataConfig.setUrl(url);
                }else{
                    log.info("## 数据库链接url为空或读取有误!");
                }
                
                String user = root.elementText("database-user");
                if(user != null && !"".equals(user)){
                    ConfigManager.dataConfig.setUser(user);
                }else{
                    log.info("## 数据库链接用户名为空或读取有误!");
                }
                
                String pwd = root.elementText("database-pwd");
                if(pwd != null && !"".equals(pwd)){
                    ConfigManager.dataConfig.setPwd(pwd);
                }else{
                    log.info("## 数据库链接密码为空或读取有误!");
                }
                
                String maxLinkConn = root.elementText("database-maxLinkConn");
                if(maxLinkConn != null && !"".equals(maxLinkConn)){
                    int maxLinkConn_ = Integer.valueOf(maxLinkConn);
                    ConfigManager.dataConfig.setMaxLinkConn(maxLinkConn_);
                }else{
                    log.info("## 数据库最大连接数为空或读取有误!");
                }
                
                String minLinkConn = root.elementText("database-minLinkConn");
                if(minLinkConn != null && !"".equals(minLinkConn)){
                    int minLinkConn_ = Integer.valueOf(minLinkConn);
                    ConfigManager.dataConfig.setMinLinkConn(minLinkConn_);
                }else{
                    log.info("## 数据库最小连接数为空或读取有误!");
                }
                
            } catch (Exception e) {
                log.error("## 服务器配置文件[serverconfig.xml]路径错误!",e);
            }
            
        }
    
    }

    数据库配置文件:

    <?xml version="1.0" encoding="GBK"?>
    <databases>
        <!-- 链接数据库驱动 -->
        <database-driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</database-driver>
        <!-- 链接数据库的Url :SelectMethod=Cursor作用:利用服务器端的游标加快速度 使用:
        1.执行多个Statements的操作时候用
        2.需要手动使用事务的时候使用
        3.使用SqlServer数据库连接url的时候使用
        -->
        <database-url>jdbc:sqlserver://200.10.10.172:1433;DatabaseName=HOD-2000;selectMethod=cursor</database-url>
        <!-- 链接数据库的用户名 -->
        <database-user>sa</database-user>
        <!-- 链接数据库的密码  -->
        <database-pwd>brt123@brt</database-pwd>
        <!-- 最大连接数 -->
        <database-maxLinkConn>50</database-maxLinkConn>
        <!-- 最小连接数 -->
        <database-minLinkConn>20</database-minLinkConn>
    </databases>
  • 相关阅读:
    7z usecaes
    最新状态
    ABAP 常用FUNCTION (最近工作中用到的)
    又是一个星期五
    阿牛
    自我定位的重要性
    smortform 创建
    换个角度想或许不一样
    为什么喜欢跟男生聊天小小分析
    BDC 代码设置
  • 原文地址:https://www.cnblogs.com/quyongjin/p/3042591.html
Copyright © 2020-2023  润新知