Mybatis-plus动态数据库之主、副数据库配置从数据库(主数据库或其它数据库都可以)读取

我卑微Java开发攻城狮一名,最近在做一个项目,Mysql、Oracle、Sql server、PostgreSql都有用到,所以需要用到动态数据库。本人采用Mybatis-plus的动态数据源,但是我这数据库有点多,放到yml不好管理、也不太安全,于是我就想到从一个数据库(主数据库)读取所有数据库信息,但是Mybatis-plus的动态数据配置是自动加载yml或properties配置文件的,所以我加了一个处理器来更改Spring中的bean,从而更改动态数据源加载配置的方法,通过读取主数据库一个表(dbs),把所有的数据库信息加载到mybatis-plus动态数据源配置信息中去,这样既方便又安全,还便于管理。话不多硕,干就完了,奥利给!

1.这是Java相关代码,当然你可以改代码,可以把副(从)数据库配置放到其他数据库,MySQL或Redis都可以

package com.qy.processor;

import com.baomidou.dynamic.datasource.DynamicDataSourceCreator;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.YmlDynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidConfig;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Because of you on 2019/12/29.
 */
@Component
@PropertySource({"classpath:db.properties"})//加载resource下的db.properties
public class DbProcessor implements BeanPostProcessor {
    @Value("${db.driver}")
    private String driver;
    @Value("${db.url}")
    private String url;
    @Value("${db.username}")
    private String username;
    @Value("${db.password}")
    private String password;
    @Value("${db.sql}")
    private String sql;
    @Autowired
    private DefaultListableBeanFactory defaultListableBeanFactory;
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //设置数据库配置
        if(StringUtils.endsWithIgnoreCase(beanName,"dynamicDataSourceProvider")) {
            boolean containsBean = defaultListableBeanFactory.containsBean("dynamicDataSourceProvider");
            if(containsBean) {
                defaultListableBeanFactory.removeBeanDefinition("dynamicDataSourceProvider");
            }
            defaultListableBeanFactory.registerBeanDefinition("dynamicDataSourceProvider", BeanDefinitionBuilder.genericBeanDefinition(DynamicDataSourceProperties.class).getBeanDefinition());
            bean = null;
            DynamicDataSourceCreator dynamicDataSourceCreator = (DynamicDataSourceCreator) defaultListableBeanFactory.getBean("dynamicDataSourceCreator");
            YmlDynamicDataSourceProvider ymlDynamicDataSourceProvider = new YmlDynamicDataSourceProvider(this.createDynamicDataSourceProperties(),dynamicDataSourceCreator);
            return ymlDynamicDataSourceProvider;
        }
        //设置主数据库
        if(StringUtils.endsWithIgnoreCase(beanName,"dataSource")) {
            DynamicRoutingDataSource dynamicRoutingDataSource = (DynamicRoutingDataSource)bean;
            dynamicRoutingDataSource.setPrimary("oracle");
            return  dynamicRoutingDataSource;
        }
        return bean;
    }
    public DynamicDataSourceProperties createDynamicDataSourceProperties() {
        Map<String,DataSourceProperty> map = new HashMap<String,DataSourceProperty>();
        DataSourceProperty mainDbProperty = new DataSourceProperty();
        //把主数据设置进去
        mainDbProperty.setDriverClassName(driver);
        mainDbProperty.setUrl(url);
        mainDbProperty.setUsername(username);
        mainDbProperty.setPassword(password);
        map.put("oracle",mainDbProperty);
        List<Map<String,String>> list = this.listDbs();
        DataSourceProperty otherDbProperty =  null;
        //设置副数据库
        for (Map<String,String> tmpMap : list) {
            otherDbProperty = new DataSourceProperty();
            String nickname = tmpMap.get("nickname");
            otherDbProperty.setDriverClassName(tmpMap.get("driver"));
            otherDbProperty.setUrl(tmpMap.get("url"));
            otherDbProperty.setUsername(tmpMap.get("username"));
            otherDbProperty.setPassword(tmpMap.get("password"));
            map.put(nickname,otherDbProperty);
        }
        DruidConfig druidConfig = this.createDruidConfig();
        DynamicDataSourceProperties dynamicDataSourceProperties = new DynamicDataSourceProperties();
        dynamicDataSourceProperties.setDruid(druidConfig);
        dynamicDataSourceProperties.setDatasource(map);
        return dynamicDataSourceProperties;
    }

    /**
     * 获取数据库连接
     * @return
     */
    public Connection getConnection() throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        return DriverManager.getConnection(url,username,password);
    }

    /**
     * 查询所有数据库配置
     * @return
     */
    public List<Map<String,String>> listDbs() {
        List<Map<String,String>> resultList = null;
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs =  null;
        try {
            connection =  this.getConnection();
            ps = connection.prepareStatement(sql);
            rs = ps.executeQuery();
            resultList = new ArrayList<Map<String,String>>();
            Map<String,String> resultMap = null;
            while (rs.next()) {
                String nickname = rs.getString("NICKNAME");
                String dbdriver = rs.getString("DRIVER");
                String dburl = rs.getString("URL");
                String dbusername = rs.getString("USERNAME");
                String dbpassword = rs.getString("PASSWORD");
                resultMap = new HashMap<String,String>();
                resultMap.put("nickname",nickname);
                resultMap.put("driver",dbdriver);
                resultMap.put("url",dburl);
                resultMap.put("username",dbusername);
                resultMap.put("password",dbpassword);
                resultList.add(resultMap);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            if(rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps!=null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            return  resultList;
        }
    }

    /**
     * 配置druid连接池配置
     * @return
     */
    public DruidConfig createDruidConfig() {
        DruidConfig druidConfig = new DruidConfig();
        druidConfig.setInitialSize(10);
        druidConfig.setMaxActive(100);
        druidConfig.setMinIdle(10);
        druidConfig.setMaxWait(60000L);
        druidConfig.setPoolPreparedStatements(true);
        druidConfig.setMaxPoolPreparedStatementPerConnectionSize(20);
        druidConfig.setTimeBetweenEvictionRunsMillis(60000L);
        druidConfig.setMinEvictableIdleTimeMillis(300000L);
        //validation-query: SELECT 1 FROM DUAL
        druidConfig.setTestWhileIdle(true);
        druidConfig.setTestOnBorrow(false);
        druidConfig.setTestOnReturn(false);
        druidConfig.setFilters("stat,wall");
        return druidConfig;
    }
}

2.我用的主数据是oracle,这是db.properties,放到Springboot resource目录下,当然你的主数据连接信息也可以加密,相关业务代码你可以自己添加

db.driver=oracle.jdbc.driver.OracleDriver
db.url=jdbc:oracle:thin:@127.0.0.1:1521:myorcl
db.username=数据库名
db.password=密码
db.sql=select nickname,driver,url,username,password from DBS

3.创建副(从)数据库配置表

create table dbs(
     id number(4) primary key,
     nickname varchar2(8) not null,
     driver varchar2(32) not null,
     url  varchar2(64) not null,
     username varchar2(32) not null,
     password varchar2(32) not null,
     create_time date,
     remark varchar2(128)
)

老铁!别走,如果我的代码可以帮到你,请给我一颗小心心。奥利给!

                                                         非学无以广才,非志无以成学。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章