欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

数据库连接池及数据库连接获取(架构师的成长之路---第4篇)

程序员文章站 2022-05-04 13:30:37
闲话少说,直接列举问题: ①AB两台数据库服务器做集群,由于两台服务器配置不一样,如何在代码中要实现每访问服务器A的数据库2次,才能访问服务器B的数据库1次。 ②AB两台数据库服务器做读写分离,如何在代码中控制,查询数据使用服务器A的数据库连接,增删改使用服务器B的数据库连接。 代码结构: 代码实现 ......

闲话少说,直接列举问题:

①ab两台数据库服务器做集群,由于两台服务器配置不一样,如何在代码中要实现每访问服务器a的数据库2次,才能访问服务器b的数据库1次。

②ab两台数据库服务器做读写分离,如何在代码中控制,查询数据使用服务器a的数据库连接,增删改使用服务器b的数据库连接。

代码结构:

数据库连接池及数据库连接获取(架构师的成长之路---第4篇)

代码实现:

①数据库连接信息默认值

package com.keji10.core.jdbc.properties;

/**
 * 类描述: 数据库连接信息默认值
 * 
 * @since 1.5
 * @version 1.0
 * @author xuanly
 * 
 */
public interface jdbcpropertiescontants {

    /**
     * jdbc.maxactive最大活跃数(默认值)
     */
    public static final int jdbc_maxactive_default = 20;
    /**
     * jdbc.maxidle最大连接数(默认值)
     */
    public static final int jdbc_maxidle_default = 20;
    /**
     * jdbc.maxwait默认等待时间(默认值)
     */
    public static final int jdbc_maxwait_default = 10000;
    /**
     * jdbc.weight默认数据库连接池权重(默认值)
     */
    public static final int jdbc_weight_default = 1;
}

package com.keji10.core.jdbc.properties;

/**
 * 类描述: 数据库配置文件实体类
 * 
 * @since 1.5
 * @version 1.0
 * @author xuanly
 * 
 */
public class jdbcpropertiesbean implements jdbcpropertiescontants {
    private string jdbcdriver;
    private string jdbcurl;
    private string jdbcusername;
    private string jdbcpassword;
    private int jdbcmaxactive;
    private int jdbcmaxidle;
    private int jdbcmaxwait;
    private int jdbcweight;

    public string getjdbcdriver() {
        return jdbcdriver;
    }

    public void setjdbcdriver(string jdbcdriver) {
        this.jdbcdriver = jdbcdriver;
    }

    public string getjdbcurl() {
        return jdbcurl;
    }

    public void setjdbcurl(string jdbcurl) {
        this.jdbcurl = jdbcurl;
    }

    public string getjdbcusername() {
        return jdbcusername;
    }

    public void setjdbcusername(string jdbcusername) {
        this.jdbcusername = jdbcusername;
    }

    public string getjdbcpassword() {
        return jdbcpassword;
    }

    public void setjdbcpassword(string jdbcpassword) {
        this.jdbcpassword = jdbcpassword;
    }

    public int getjdbcweight() {
        if (jdbcweight == 0) {
            // 返回默认值
            return jdbc_weight_default;
        }
        return jdbcweight;
    }

    public void setjdbcweight(int jdbcweight) {
        this.jdbcweight = jdbcweight;
    }

    public int getjdbcmaxactive() {
        if (jdbcmaxactive == 0) {
            // 返回默认值
            return jdbc_maxactive_default;
        }
        return jdbcmaxactive;
    }

    public void setjdbcmaxactive(int jdbcmaxactive) {
        this.jdbcmaxactive = jdbcmaxactive;
    }

    public int getjdbcmaxidle() {
        if (jdbcmaxidle == 0) {
            // 返回默认值
            return jdbc_maxidle_default;
        }
        return jdbcmaxidle;
    }

    public void setjdbcmaxidle(int jdbcmaxidle) {
        this.jdbcmaxidle = jdbcmaxidle;
    }

    public int getjdbcmaxwait() {
        if (jdbcmaxwait == 0) {
            // 返回默认值
            return jdbc_maxwait_default;
        }
        return jdbcmaxwait;
    }

    public void setjdbcmaxwait(int jdbcmaxwait) {
        this.jdbcmaxwait = jdbcmaxwait;
    }

    public string tostring() {
        stringbuffer s = new stringbuffer();
        s.append("jdbcdriver    =" + jdbcdriver);
        s.append("jdbcurl       =" + jdbcurl);
        s.append("jdbcusername  =" + jdbcusername);
        s.append("jdbcpassword  =" + jdbcpassword);
        s.append("jdbcmaxactive =" + jdbcmaxactive);
        s.append("jdbcmaxidle   =" + jdbcmaxidle);
        s.append("jdbcmaxwait   =" + jdbcmaxwait);
        s.append("jdbcweight    =" + jdbcweight);
        return s.tostring();
    }
}

 ③数据库配置文件信息获取

package com.keji10.core.jdbc.properties;

import java.util.resourcebundle;

import org.apache.log4j.logger;

import com.keji10.core.exception.dbexception;

/**
 * 类描述: 数据库配置文件信息获取
 * 
 * @since 1.5
 * @version 1.0
 * @author xuanly
 * 
 */
public class jdbcpropertiesmanager {
    private logger logger = logger.getlogger(jdbcpropertiesmanager.class.getname());
    // 单例模式begin
    private static jdbcpropertiesmanager instance = new jdbcpropertiesmanager();

    private jdbcpropertiesmanager() {
    }

    public static jdbcpropertiesmanager getinstance() {
        return instance;
    }

    // 单例模式end
    private jdbcpropertiesbean jdbcpropertiesbean;

    /**
     * 获取jdbc.propertiesbean配置文件
     * 
     * @return jdbcpropertiesbean
     * @throws dbexception
     */
    public jdbcpropertiesbean getjdbcpropertiesbean() throws dbexception {
        return getjdbcpropertiesbean("jdbc");
    }

    public jdbcpropertiesbean getjdbcpropertiesbean(string propertiefile) throws dbexception {
        resourcebundle rb = resourcebundle.getbundle(propertiefile);
        jdbcpropertiesbean = new jdbcpropertiesbean();
        try {
            jdbcpropertiesbean.setjdbcdriver(rb.getstring("jdbc.driver"));
            jdbcpropertiesbean.setjdbcurl(rb.getstring("jdbc.url"));
            jdbcpropertiesbean.setjdbcusername(rb.getstring("jdbc.username"));
            jdbcpropertiesbean.setjdbcpassword(rb.getstring("jdbc.password"));
        } catch (exception e) {
            logger.warn("获取数据库连接配置文件【jdbc.driver】失败,执行无法启动!");
            logger.warn("获取数据库连接配置文件【jdbc.url】失败,执行无法启动!");
            logger.warn("获取数据库连接配置文件【jdbc.username】失败,执行无法启动!");
            logger.warn("获取数据库连接配置文件【jdbc.password】失败,执行无法启动!");
            logger.error(e);
            throw new dbexception(e);
        }
        try {
            jdbcpropertiesbean.setjdbcmaxactive(integer.valueof(rb.getstring("jdbc.maxactive")));
            jdbcpropertiesbean.setjdbcmaxidle(integer.valueof(rb.getstring("jdbc.maxidle")));
            jdbcpropertiesbean.setjdbcmaxwait(integer.valueof(rb.getstring("jdbc.maxwait")));
            jdbcpropertiesbean.setjdbcweight(integer.valueof(rb.getstring("jdbc.weight")));
        } catch (exception e) {
            logger.warn("获取数据库连接配置文件【jdbc.maxactive】失败,系统将执行默认配置");
            logger.warn("获取数据库连接配置文件【jdbc.maxidle】失败,系统将执行默认配置");
            logger.warn("获取数据库连接配置文件【jdbc.maxwait】失败,系统将执行默认配置");
            logger.warn("获取数据库连接配置文件【jdbc.weight】失败,系统将执行默认配置");
        }
        return jdbcpropertiesbean;
    }

}

④数据库连接池管理

package com.keji10.core.jdbc.datasource;

import java.util.hashmap;
import java.util.map;

import javax.sql.datasource;

import org.apache.commons.dbcp.basicdatasource;
import org.apache.log4j.logger;

import com.keji10.core.commons.configbean;
import com.keji10.core.exception.dbexception;
import com.keji10.core.jdbc.properties.jdbcpropertiesbean;
import com.keji10.core.jdbc.properties.jdbcpropertiesmanager;

/**
 * 类描述:数据库连接池管理
 * 
 * @since 1.5
 * @version 1.0
 * @author chenairu
 * 
 */
public class dbdatasource {
    private logger logger = logger.getlogger(dbdatasource.class.getname());
    // 单例模式begin
    private static dbdatasource instance = new dbdatasource();

    private dbdatasource() {
    }

    public static dbdatasource getinstance() {
        return instance;
    }

    // 单例模式end
    // 非主数据库连接池集群池
    private map<string, datasource> otherdatasourcemap = new hashmap<string, datasource>();
    // 主数据库连接池集群池
    private map<integer, datasource> maindatasourcemap = new hashmap<integer, datasource>();
    // 记录数据库负载均衡的配置
    private map<integer, integer> maindatasourceweightmap = new hashmap<integer, integer>();
    // 记录获取数据库连接的指针
    private int maindatasourceweightindex = 0;

    /**
     * 获取连接池
     * 
     * @param bean
     * @return
     * @throws dbexception
     */
    public datasource getdatasource(jdbcpropertiesbean bean) throws dbexception {
        if (bean == null) {
            return getdatasource();
        }
        if (bean.getjdbcdriver() == null || bean.getjdbcurl() == null || bean.getjdbcusername() == null || bean.getjdbcpassword() == null) {
            logger.error("********数据库配置信息不完整!!!*********");
            logger.error("*********加载默认数据库配置!!!*********");
            return getdatasource();
        }
        datasource datasource = (datasource) otherdatasourcemap.get(bean.tostring());
        if (datasource != null) {
            return datasource;
        }
        logger.info("*********加载数据库配置***********************");
        logger.info("jdbcdriver   =" + bean.getjdbcdriver());
        logger.info("jdbcurl      =" + bean.getjdbcurl());
        logger.info("jdbcusername =" + bean.getjdbcusername());
        logger.info("jdbcpassword =" + bean.getjdbcpassword());
        logger.info("jdbcmaxactive=" + bean.getjdbcmaxactive());
        logger.info("jdbcmaxidle  =" + bean.getjdbcmaxidle());
        logger.info("jdbcmaxwait  =" + bean.getjdbcmaxwait());
        basicdatasource basicdatasource = new basicdatasource();
        basicdatasource.setdriverclassname(bean.getjdbcdriver());
        basicdatasource.seturl(bean.getjdbcurl());
        basicdatasource.setusername(bean.getjdbcusername());
        basicdatasource.setpassword(bean.getjdbcpassword());
        basicdatasource.setmaxactive(bean.getjdbcmaxactive());
        basicdatasource.setmaxidle(bean.getjdbcmaxidle());
        basicdatasource.setmaxwait(bean.getjdbcmaxwait());
        datasource = basicdatasource;
        logger.info("*********加载数据库配置完成************************");
        otherdatasourcemap.put(bean.tostring(), datasource);
        return datasource;
    }

    /**
     * 获取连接池
     * 
     * @return 连接池
     * @throws dbexception
     */
    public datasource getdatasource() throws dbexception {
        string jdbcfilename;
        jdbcpropertiesbean bean;
        datasource datasource;
        string jdbcs = configbean.getinstance().getjdbcs();
        if (maindatasourcemap.isempty()) {
            for (int i = 0; i < jdbcs.split(",").length; i++) {
                jdbcfilename = jdbcs.split(",")[i];
                bean = jdbcpropertiesmanager.getinstance().getjdbcpropertiesbean(jdbcfilename);
                logger.info("*********加载数据库配置***********************");
                logger.info("jdbcdriver   =" + bean.getjdbcdriver());
                logger.info("jdbcurl      =" + bean.getjdbcurl());
                logger.info("jdbcusername =" + bean.getjdbcusername());
                logger.info("jdbcpassword =" + bean.getjdbcpassword());
                logger.info("jdbcmaxactive=" + bean.getjdbcmaxactive());
                logger.info("jdbcmaxidle  =" + bean.getjdbcmaxidle());
                logger.info("jdbcmaxwait  =" + bean.getjdbcmaxwait());
                logger.info("jdbcweight   =" + bean.getjdbcweight());
                basicdatasource basicdatasource = new basicdatasource();
                basicdatasource.setdriverclassname(bean.getjdbcdriver());
                basicdatasource.seturl(bean.getjdbcurl());
                basicdatasource.setusername(bean.getjdbcusername());
                basicdatasource.setpassword(bean.getjdbcpassword());
                basicdatasource.setmaxactive(bean.getjdbcmaxactive());
                basicdatasource.setmaxidle(bean.getjdbcmaxidle());
                basicdatasource.setmaxwait(bean.getjdbcmaxwait());
                datasource = basicdatasource;
                //负载设置关键代码---begin
                maindatasourcemap.put(i, datasource);
                for (int j = 0; j < bean.getjdbcweight(); j++) {
                    maindatasourceweightmap.put(maindatasourceweightmap.size() + 1, i);
                }
                //负载设置关键代码---end
                logger.info("*********加载数据库配置完成************************");
            }
        }
        int maindatasourcenowindex;
        try {
            maindatasourcenowindex = maindatasourceweightmap.get(maindatasourceweightindex % (maindatasourceweightmap.size()));
            maindatasourceweightindex++;
            if (maindatasourceweightindex >= maindatasourceweightmap.size()) {
                maindatasourceweightindex = 0;
            }
        } catch (exception e) {
            maindatasourcenowindex = 0;
        }
        return (datasource) maindatasourcemap.get(maindatasourcenowindex);
    }

    /**
     * 清空数据库连接池
     */
    public void clear() {
        otherdatasourcemap.clear();
        maindatasourcemap.clear();
        maindatasourceweightmap.clear();
        maindatasourceweightindex = 0;
    }
}

 

  ⑤数据库连接实现

package com.keji10.core.jdbc.datasource;

import java.sql.connection;
import java.sql.sqlexception;

import javax.sql.datasource;

import org.apache.log4j.logger;

import com.keji10.core.exception.dbexception;
import com.keji10.core.jdbc.properties.jdbcpropertiesbean;

/**
 * 类描述:数据库连接实现
 * 
 * @since 1.5
 * @version 1.0
 * @author xuanly
 * 
 */
public class dbconnection {
    private logger logger = logger.getlogger(dbconnection.class.getname());
    // 单例模式begin
    private static dbconnection instance = new dbconnection();

    private dbconnection() {
    }

    public static dbconnection getinstance() {
        return instance;
    }

    // 单例模式end
    /**
     * 获取默认数据库连接
     * 
     * @return 数据库连接
     * @throws dbexception
     */
    public connection getconnection() throws dbexception {
        try {
            return dbdatasource.getinstance().getdatasource().getconnection();
        } catch (sqlexception e) {
            logger.error(e);
            throw new dbexception(e);
        }
    }

    /**
     * 根据配置文件获取自定义数据库连接
     * 
     * @param jdbcpropertiesbean
     * @return
     * @throws dbexception
     */
    public connection getconnection(jdbcpropertiesbean jdbcpropertiesbean) throws dbexception {
        datasource datasource = dbdatasource.getinstance().getdatasource(jdbcpropertiesbean);
        try {
            return datasource.getconnection();
        } catch (sqlexception e) {
            logger.error(e);
            throw new dbexception(e);
        }
    }

    /**
     * 关闭数据库连接
     * 
     * @throws dbexception
     */
    public void close(connection connection) throws dbexception {
        try {
            if (connection == null) {
                return;
            }
            if (connection.isclosed()) {
                return;
            }
            if (connection != null) {
                connection.close();
                connection = null;
            }
        } catch (sqlexception e) {
            logger.error(e);
            throw new dbexception(e);
        } finally {
            connection = null;
        }
    }

    /**
     * 清空数据库连接池
     */
    public void clear() {
        dbdatasource.getinstance().clear();
    }
}

 

封装框架最核心的部分,莫过于数据库连接的封装。数据库连接就像一条管道,一端连着数据库,一端连接java程序。

如果一个框架,能够像数据库连接一样,一端连着数据库,一端连着用户的界面,中间无需编辑java代码,即可完成项目开发。

那这套框架的思路将会为以后的开发,开辟一个新模式。

计划安排,下一编先把对象映射完成,再写数据库查询的封装。