栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java使用druid配置多数据源(获取数据库源) AbstractRoutingDataSource

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java使用druid配置多数据源(获取数据库源) AbstractRoutingDataSource

书接上文使用nacos配置多数据源(druid)AbstractRoutingDataSource需要先阅读此篇文章

根据配置文件切换数据源讲了,但对于某些特殊场景可能依旧有点问题,比如通过数据源生成代码,导出文档什么的,可能会有多个数据源,而且这些数据源肯定是不会走nacos的所以就有了本篇文章,写的很糙请谅解,可以自己优化

修改了多数据源bean的配置类

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasypt.encryption.StringEncryptor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.support.JdbcUtils;


import javax.sql.DataSource;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;


@Configuration
public class MultipleDataSourceConfig  {
    private static final Log logger = LogFactory.getLog(JdbcUtils.class);
    private final StringEncryptor stringEncryptor;

    public MultipleDataSourceConfig(StringEncryptor stringEncryptor) {
        this.stringEncryptor = stringEncryptor;
    }

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource createMasterDataSource(){
        return new DruidDataSource();
    }

    @Bean("slave1")
    @ConfigurationProperties(prefix = "spring.datasource.slave1")
    public DataSource createSlave1DataSource(){
        return new DruidDataSource();
    }

    
    @Bean
    @Primary
    public DataSource createDynamicDataSource(@Qualifier("master") DataSource master, @Qualifier("slave1") DataSource slave1) {

        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        //设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(master);
        //配置多数据源
        Map map = new HashMap<>(16);
        map.put("master",master);
        map.put("slave1",slave1);
        Statement stmt =null;
        try {
             stmt = master.getConnection().createStatement();
            // 储存数据源的表datasource_data
            ResultSet rs = stmt.executeQuery("select * from  salaryother.datasource_data where del_flag = 0");
            while (rs.next()) {
                DruidDataSource druidDataSource = new DruidDataSource();
                BeanUtils.copyProperties(master,druidDataSource);
                //配置驱动,直接使用master的其他配置数据包括驱动需要定制化需要自己配置              if(StringUtils.isNotBlank(rs.getString("driver_class_name"))){
                    druidDataSource.setDriverClassName(rs.getString("driver_class_name"));
                }
                try {
                    druidDataSource.setName(rs.getString("name"));
                    druidDataSource.setUrl(rs.getString("url"));
                    druidDataSource.setUsername(rs.getString("username"));
                    druidDataSource.setPassword(stringEncryptor.decrypt(rs.getString("password")));
                    DriverManager.getConnection(druidDataSource.getUrl(),druidDataSource.getUsername(),druidDataSource.getPassword());
                    map.put(rs.getString("name"), druidDataSource);
                }catch (SQLException e){
                    logger.error(rs.getString("name")+"数据源初始化异常---连接失败", e);
                }

            }
            logger.info(rs.toString()+"------------------------------------");
        } catch (Exception var8) {
            var8.printStackTrace();
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException var2) {
                    logger.trace("Could not close JDBC Statement", var2);
                } catch (Throwable var3) {
                    logger.trace("Unexpected exception on closing JDBC Statement", var3);
                }
            }
        }
        dynamicDataSource.setTargetDataSources(map);
        return  dynamicDataSource;
    }



}

修改

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.Map;


public class DynamicDataSource extends AbstractRoutingDataSource {

    Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {

       Map resolvedDataSources = getResolvedDataSources();
        if(resolvedDataSources.containsKey(DynamicDataSourceSwitcher.getDataSource())){
            Connection connection =null;
            try {
                 connection = resolvedDataSources.get(DynamicDataSourceSwitcher.getDataSource()).getConnection();
                logger.info("------------------当前数据源 {}", DynamicDataSourceSwitcher.getDataSource());
            }catch (Exception e){
                logger.info("------------------当前数据源失效,切换为主数据源",e);
                DynamicDataSourceSwitcher.setDataSource(DynamicDataSourceSwitcher.MATER);
            }finally {
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException var2) {
                        logger.trace("Could not close JDBC Statement", var2);
                    } catch (Throwable var3) {
                        logger.trace("Unexpected exception on closing JDBC Statement", var3);
                    }
                }
            }
        }else {
            logger.info("数据源中不包含切换源----------当前数据源 {}", DynamicDataSourceSwitcher.MATER);
        }


        return DynamicDataSourceSwitcher.getDataSource();
    }

增加对数据库操作 service层

private final StringEncryptor stringEncryptor;
	@Qualifier("createDynamicDataSource")
	private  DynamicDataSource dataSource;

	
	@Override
	public Boolean saveSysDatasource(DatasourceData datasourceData) {

		//校验数据源配置是否能链接
		try {
			DriverManager.getConnection(datasourceData.getUrl(), datasourceData.getUsername(), datasourceData.getPassword());
		}catch (SQLException e){
			log.error(e.getMessage(), e);
			throw new RuntimeException("连接失败,请检查配置信息:" + e.getMessage());
		}

		//添加动态数据源
//		DynamicDataSource dynamicDataSource = new DynamicDataSource();
		Map map = new HashMap<>(16);
		DruidDataSource druidDataSource = new DruidDataSource();
		druidDataSource.setName(datasourceData.getName());
		druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		if(StringUtils.isNotBlank(datasourceData.getDriverClassName())){
			druidDataSource.setDriverClassName(datasourceData.getDriverClassName());
		}
		druidDataSource.setUrl(datasourceData.getUrl());
		druidDataSource.setUsername(datasourceData.getUsername());
		druidDataSource.setPassword(datasourceData.getPassword());
		map.put(datasourceData.getName(), druidDataSource);
		dataSource.setTargetDataSources(map);
		dataSource.afterPropertiesSet();
		datasourceData.setPassword(stringEncryptor.encrypt(datasourceData.getPassword()));
		datasourceData.setTenantId(null);
		this.baseMapper.insert(datasourceData);
		return Boolean.TRUE;
	}

	
	@Override
	public Boolean updateSysDatasource(DatasourceData datasourceData) {
		//校验数据源配置是否能链接
		try {
			DriverManager.getConnection(datasourceData.getUrl(),datasourceData.getUsername(),datasourceData.getPassword());
		}catch (SQLException e){
			log.error(e.getMessage(), e);
			throw new RuntimeException("连接失败,请检查配置信息:" + e.getMessage());
		}
		//先删除动态数据源
		DynamicDataSourceSwitcher.cleanDataSource();
		Map resolvedDataSources = dataSource.getResolvedDataSources();
		if(resolvedDataSources.containsKey(datasourceData.getName())){
			resolvedDataSources.remove(datasourceData.getName());
		}
		//再添加动态数据源
//		DynamicDataSource dynamicDataSource = new DynamicDataSource();
		Map map = new HashMap<>(16);
		DruidDataSource druidDataSource = new DruidDataSource();
		druidDataSource.setName(datasourceData.getName());
		druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		if(StringUtils.isNotBlank(datasourceData.getDriverClassName())){
			druidDataSource.setDriverClassName(datasourceData.getDriverClassName());
		}
		druidDataSource.setUrl(datasourceData.getUrl());
		druidDataSource.setUsername(datasourceData.getUsername());
		druidDataSource.setPassword(datasourceData.getPassword());
		map.put(datasourceData.getName(), druidDataSource);
		dataSource.setTargetDataSources(map);
		dataSource.afterPropertiesSet();
		if (StringUtils.isNotBlank(datasourceData.getPassword())) {
			datasourceData.setPassword(stringEncryptor.encrypt(datasourceData.getPassword()));
		}
		this.baseMapper.updateById(datasourceData);
		return Boolean.TRUE;
	}
@Data
@ApiModel(value="数据源表")
@TableName("datasource_data")
@EqualsAndHashCode(callSuper = true)
public class DatasourceData extends Model {
	private static final long serialVersionUID = 1L;

	
	@ApiModelProperty(value = "主键")
	@TableId(type = IdType.ASSIGN_ID)
	private String id;
	
	@ApiModelProperty(value = "名称")
	@NotBlank(message = "数据源名称不能为空")
	private String name;
	
	@ApiModelProperty(value = "jdbcurl")
	@NotBlank(message = "jdbcurl不能为空")
	private String url;
	
	@ApiModelProperty(value = "用户名")
	@NotBlank(message = "用户名不能为空")
	private String username;
	
	@ApiModelProperty(value = "密码")
	@NotBlank(message = "密码不能为空")
	private String password;
	
	@ApiModelProperty(value = "驱动")
	@NotBlank(message = "驱动不能为空")
	private String driverClassName;
	
	@ApiModelProperty(value = "创建时间")
	private LocalDateTime createTime;
	
	@ApiModelProperty(value = "更新时间")
	private LocalDateTime updateTime;
	
	@ApiModelProperty(value = "删除标记")
	private String delFlag;
	
	@ApiModelProperty(value = "租户ID")
	private String tenantId;

}

获取数据库表名列表和表字段



	

	
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271622.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号