SpringBoot动态切换数据源

动态切换数据源

  在实际项目开发中,需要用到动态切换数据库调取不同数据库的数据进行处理,以下是我亲身实现的一种方式,在实际项目中已用到。
  1.如从库的表结构一致,则可以使用一个HTTP接口处理相同的业务,只是区分不同的库
  如有疑问,请指出!

在这里插入图片描述
1.启动时首先会默认连接主数据库(数据库配置配置在配置文件中,代码读取,创建数据源连接)
2.连接好主库数据源后读取主库存取的多数据库地址,用户名,密码,配置表
3.根据前端传入code值来区分所要查询的数据库

以下是代码部分

一、配置文件配置(config.properties)

#多数据源配置初始化连接主库地址
dbUrl=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
#主库连接用户名
dbUsername=root
#主库连接密码
dbPassword=root
########projectDBMgr 用于存储所有的数据库地址及用户名及密码
#主库code码 作为key
projectCode=project_001
# 作为value 程序启动时默认连接主数据库名 用于查询数据库存储的所有从库的地址、用户名、及密码
dbName=自己的数据库名称
#主库主机本地  127.0.0.1
dbIp=127.0.0.1

application.yml文件

spring:
  datasource:
    url: jdbc:mysql://%s:3306/%s?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
    #url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
    driverClassName: com.mysql.jdbc.Driver
    username: root
    password: root

1.url需要使用占位符%s
2.我这里用数据库用户名密码是默认的,改为自己的即可
3.数据库驱动根据自己的版本

pom.xml文件
以下是我的jar包文件,可挑选自己可用的

	<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <mybaitsplus.version>2.1.9</mybaitsplus.version>
        <!--<mybatis.version>3.2.6</mybatis.version>-->
        <!-- log4j日志文件管理包版本 -->
        <slf4j.version>1.7.7</slf4j.version>
        <logback.version>1.1.3</logback.version>
        <log4j.version>1.2.17</log4j.version>
        <mybatis-plus-boot-starter.version>3.0-RC3</mybatis-plus-boot-starter.version>
        <HikariCP.version>3.2.0</HikariCP.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>



        <!-- mybatis-plus begin -->
       <!-- <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-boot-starter.version}</version>
        </dependency>-->
        <!-- mybatis-plus end -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.41</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--mysql链接依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
            <version>7.0.81</version>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
        <!-- Spring Boot 缓存支持启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <!-- 格式化对象,方便输出日志 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.41</version>
        </dependency>
        <!-- log end -->
        <!-- 映入JSON -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>
        <!-- 上传组件包 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <!-- JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- JSTL实现包 -->
        <dependency>
            <groupId>org.apache.taglibs</groupId>
            <artifactId>taglibs-standard-impl</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- MD5实现包   -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--CORS Filter 跨域支持 -->
        <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>cors-filter</artifactId>
            <version>1.7.1</version>
        </dependency>
        <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>java-property-utils</artifactId>
            <version>1.9</version>
        </dependency>
        <!--日期格式化-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <!--二维码生成工具包-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.0</version>
        </dependency>

        <!-- dubbo 服务-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
            <type>jar</type>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 导入java ee jar 包 -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
        <!-- 导入Mysql数据库链接jar包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>

       <!-- <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0-RC3</version>
        </dependency>-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>${mybaitsplus.version}</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- 模板引擎 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
        <!--<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.1.9</version>
        </dependency>-->
    </dependencies>
    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <build.profile.id>dev</build.profile.id>
            </properties>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <build.profile.id>test</build.profile.id>
            </properties>
        </profile>
    </profiles>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/webapp</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

二、Config配置类

我使用的是mybatis plus,所以创建sqlsessionfactory会话工厂需使用mybaits plus的,我这里根据mybatis-plus官网一样,单另写了一个类,如你使用mybatis的,可以把下面注释打开,不需要增加mybatisplusConfig类

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.*;

/**
 * 数据源配置管理。
 *
 * @author zyy
 * @version 2019年11月04日
 */
@Configuration
@MapperScan(basePackages="com.bt.tunnel.mapper", value="MybatisSqlSessionFactoryBean")
public class DataSourceConfig {
	Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
	/**
	 * 根据配置参数创建数据源。使用派生的子类。
	 * @return 数据源
	 */
	@Bean(name="dataSource")
	@ConfigurationProperties(prefix="spring.datasource")
	public DataSource getDataSource() {
		logger.info("创建数据源,读取url地址并初始化...");
		String dbUrl = PropUtils.getProp("dbUrl");
		String dbUsername = PropUtils.getProp("dbUsername");
		String dbPassword = PropUtils.getProp("dbPassword");
		DataSourceBuilder builder = DataSourceBuilder.create();
		builder.url(dbUrl);
		builder.username(dbUsername);
		builder.password(dbPassword);
		builder.type(DynamicDataSource.class);
		DataSource build = builder.build();
		try {
			Connection connection = build.getConnection();
			Statement statement = connection.createStatement();
			ResultSet resultSet = statement.executeQuery("select * from url");
			while (resultSet.next()) {
				int id = resultSet.getInt("id");
				String host = resultSet.getString("dbname");
				String ip = resultSet.getString("ip");
				String projectCode = resultSet.getString("code");
				String username = resultSet.getString("username");
				String password = resultSet.getString("password");
				ProjectDBMgr.dbNameMap.put(projectCode, host);
				ProjectDBMgr.dbIPMap.put(projectCode, ip);
				ProjectDBMgr.dbUserName.put(projectCode,username);
				ProjectDBMgr.dbPassword.put(projectCode,password);
			}
			logger.info("初始化完成...");
		} catch (SQLException e) {

			e.printStackTrace();
		}
		return builder.build();
	}
	
	/**
	 * 创建会话工厂。
	 * 
	 * @param dataSource 数据源
	 * @return 会话工厂
	 */
	/*@Bean(name="MybatisSqlSessionFactoryBean")
	public MybatisSqlSessionFactoryBean getSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) {
		MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		
		try {

			return (MybatisSqlSessionFactoryBean) bean.getObject();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}*/
}

mybstis plus config


import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @author zyy
 * @date 2019/11/4 13:59
 * @description
 */
@Configuration
public class MybatisPlusConfig {
    @Resource
    private DataSource dataSource;

    @Autowired
    private MybatisProperties properties;

    @Autowired
    private ResourceLoader resourceLoader = new DefaultResourceLoader();

    @Autowired(required = false)
    private Interceptor[] interceptors;

    @Autowired(required = false)
    private DatabaseIdProvider databaseIdProvider;

    /**
     *   mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }
    /**
     * 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定
     * 配置文件和mybatis-boot的配置文件同步
     * @return
     */
    @Bean
    public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() {
        MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
        mybatisPlus.setDataSource(dataSource);
        mybatisPlus.setVfs(SpringBootVFS.class);
        if (StringUtils.hasText(this.properties.getConfigLocation())) {
            mybatisPlus.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
        }
        mybatisPlus.setConfiguration(properties.getConfiguration());
        if (!ObjectUtils.isEmpty(this.interceptors)) {
            mybatisPlus.setPlugins(this.interceptors);
        }
        MybatisConfiguration mc = new MybatisConfiguration();
        mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        mybatisPlus.setConfiguration(mc);
        if (this.databaseIdProvider != null) {
            mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
        }
        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
            mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        }
        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
            mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        }
        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
            mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
        }
        return mybatisPlus;
    }

}

三、数据源相关,定时清理无用的连接


import java.util.TimerTask;

/**
 * 清除空闲连接任务。
 * 
 * @author zyy
 * @version 2019年11月04日
 */
public class ClearIdleTimerTask extends TimerTask {
	
	@Override
	public void run() {
		DDSHolder.instance().clearIdleDDS();
	}
}


/**
 * 数据库标识管理类。用于区分数据源连接的不同数据库。
 *
 * @author zyy
 * @version 2019年11月04日
 */
public class DBIdentifier {
	
	/**
	 * 用不同的工程编码来区分数据库
	 */
	private static ThreadLocal<String> projectCode = new ThreadLocal<String>();

	public static String getProjectCode() {
		return projectCode.get();
	}

	public static void setProjectCode(String code) {
		projectCode.set(code);
	}
}


import org.apache.tomcat.jdbc.pool.DataSource;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;

/**
 * 动态数据源管理器。
 *
 * @author zyy
 * @version 2019年11月04日
 */
public class DDSHolder {
	
	/**
	 * 管理动态数据源列表。<工程编码,数据源>
	 */
	private Map<String, DDSTimer> ddsMap = new HashMap<String, DDSTimer>();

	/**
	 * 通过定时任务周期性清除不使用的数据源
	 */
	private static Timer clearIdleTask = new Timer();
	static {
		clearIdleTask.schedule(new ClearIdleTimerTask(), 5000, 60 * 1000);
	};

	private DDSHolder() {

	}

	/*
	 * 获取单例对象
	 */
	public static DDSHolder instance() {
		return DDSHolderBuilder.instance;
	}

	/**
	 * 添加动态数据源。
	 *
	 * @param projectCode 项目编码
	 * @param dds dds
	 */
	public synchronized void addDDS(String projectCode, DataSource dds) {

		DDSTimer ddst = new DDSTimer(dds);
		ddsMap.put(projectCode, ddst);
	}

	/**
	 * 查询动态数据源
	 *
	 * @param projectCode 项目编码
	 * @return dds
	 */
	public synchronized DataSource getDDS(String projectCode) {

		if (ddsMap.containsKey(projectCode)) {
			DDSTimer ddst = ddsMap.get(projectCode);
			ddst.refreshTime();
			return ddst.getDds();
		}

		return null;
	}

	/**
	 * 清除超时无人使用的数据源。
	 */
	public synchronized void clearIdleDDS() {

		Iterator<Entry<String, DDSTimer>> iter = ddsMap.entrySet().iterator();
		for (; iter.hasNext(); ) {
			
			Entry<String, DDSTimer> entry = iter.next();
			if (entry.getValue().checkAndClose())
			{
				iter.remove();
			}
		}
	}
	
	/**
	 * 单例构件类
	 * @author elon
	 * @version 2018年2月26日
	 */
	private static class DDSHolderBuilder {
		private static DDSHolder instance = new DDSHolder();
	}
}



import org.apache.tomcat.jdbc.pool.DataSource;

/**
 * 动态数据源定时器管理。长时间无访问的数据库连接关闭。
 *
 * @author zyy
 * @version 2019年11月04日
 */
public class DDSTimer {
	
	/**
	 * 空闲时间周期。超过这个时长没有访问的数据库连接将被释放。默认为10分钟。
	 */
	private static long idlePeriodTime = 10 * 60 * 1000;
	
	/**
	 * 动态数据源
	 */
	private DataSource dds;
	
	/**
	 * 上一次访问的时间
	 */
	private long lastUseTime;
	
	public DDSTimer(DataSource dds) {
		this.dds = dds;
		this.lastUseTime = System.currentTimeMillis();
	}
	
	/**
	 * 更新最近访问时间
	 */
	public void refreshTime() {
		lastUseTime = System.currentTimeMillis();
	}
	
	/**
	 * 检测数据连接是否超时关闭。
	 * 
	 * @return true-已超时关闭; false-未超时
	 */
	public boolean checkAndClose() {
		
		if (System.currentTimeMillis() - lastUseTime > idlePeriodTime)
		{
			dds.close();
			return true;
		}
		
		return false;
	}

	public DataSource getDds() {
		return dds;
	}
}


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 定义动态数据源派生类。从基础的DataSource派生,动态性自己实现。
 * @author zyy
 * @version 2019年11月04日
 */
public class DynamicDataSource extends DataSource {

    private static Logger log = LogManager.getLogger(DynamicDataSource.class);

    /**
     * 改写本方法是为了在请求不同工程的数据时去连接不同的数据库。
     */
    @Override
    public Connection getConnection(){

        String projectCode = DBIdentifier.getProjectCode();

        //1、获取数据源
        DataSource dds = DDSHolder.instance().getDDS(projectCode);

        //2、如果数据源不存在则创建
        if (dds == null) {
            try {
                DataSource newDDS = initDDS(projectCode);
                DDSHolder.instance().addDDS(projectCode, newDDS);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                log.error("Init data source fail. projectCode:" + projectCode);
                return null;
            }
        }

        dds = DDSHolder.instance().getDDS(projectCode);
        try {
            return dds.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 以当前数据对象作为模板复制一份。
     *
     * @return dds
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    private DataSource initDDS(String projectCode) throws IllegalArgumentException, IllegalAccessException {
        DataSource dds = new DataSource();
        // 2、复制PoolConfiguration的属性
        PoolProperties property = new PoolProperties();
        Field[] pfields = PoolProperties.class.getDeclaredFields();
        for (Field f : pfields) {
            f.setAccessible(true);
            Object value = f.get(this.getPoolProperties());
            try
            {
                f.set(property, value);
            }
            catch (Exception e)
            {
                //有一些static final的属性不能修改。忽略。
                log.info("Set value fail. attr name:" + f.getName());
                continue;
            }
        }
        dds.setPoolProperties(property);

        // 3、设置数据库名称和IP(一般来说,端口和用户名、密码都是统一固定的)
        String urlFormat = this.getUrl();
        String url = String.format(urlFormat, ProjectDBMgr.instance().getDBIP(projectCode),
                ProjectDBMgr.instance().getDBName(projectCode));
        dds.setUsername(ProjectDBMgr.instance().getUserame(projectCode));
        dds.setPassword(ProjectDBMgr.instance().getPassword(projectCode));
        dds.setUrl(url);
        return dds;
    }
}

四、项目数据库管理

1.我这里用到的map
数据库code值:数据库名称
数据库code值:数据库用户名
数据库code值:数据库密码
数据库code值:数据库IP地址



import java.util.HashMap;
import java.util.Map;

/**
 * 项目数据库管理。提供根据项目编码查询数据库名称和IP的接口。
 * @author zyy
 * @version 2019年11月04日
 */
public class ProjectDBMgr {
	
	/**
	 * 保存项目编码与数据名称的映射关系。这里是硬编码,实际开发中这个关系数据可以保存到redis缓存中;
	 * 新增一个项目或者删除一个项目只需要更新缓存。到时这个类的接口只需要修改为从缓存拿数据。
	 */
	public static Map<String, String> dbNameMap = new HashMap<String, String>();

	public static Map<String, String> dbUserName = new HashMap<String, String>();

	public static Map<String, String> dbPassword = new HashMap<String, String>();

	/*配置文件读取*/
	String propDbProjectCode = PropUtils.getProp("projectCode");
	String propDbName = PropUtils.getProp("dbName");
	String propDbIp = PropUtils.getProp("dbIp");
	String propDbUsername = PropUtils.getProp("dbUsername");
	String propDbPassword = PropUtils.getProp("dbPassword");

	/**
	 * 保存项目编码与数据库IP的映射关系。
	 */
	public static Map<String, String> dbIPMap = new HashMap<String, String>();

	private String projectCode1 = null;


	
	private ProjectDBMgr() {
	}
	
	public static ProjectDBMgr instance() {
		return ProjectDBMgrBuilder.instance;
	}

	public String getDBName(String projectCode) {
		this.projectCode1 = projectCode;
		if(projectCode==null){
			//默认给主库连接
			projectCode = propDbProjectCode;
			dbNameMap.put(propDbProjectCode, propDbName);
		}
		if (dbNameMap.containsKey(projectCode)) {
			return dbNameMap.get(projectCode);
		}
		return "";
	}

	public String getDBIP(String projectCode) {
		if(projectCode==null){
			//默认给主库连接
			projectCode = propDbProjectCode;
			dbIPMap.put(propDbProjectCode, propDbIp);
		}
		if (dbIPMap.containsKey(projectCode)) {
			return dbIPMap.get(projectCode);
		}
		return "";
	}


	public String getUserame(String projectCode) {
		if(projectCode==null){
			//默认给主库连接
			projectCode = propDbProjectCode;
			dbUserName.put(propDbProjectCode, propDbUsername);
		}
		if (dbUserName.containsKey(projectCode)) {
			return dbUserName.get(projectCode);
		}
		return "";
	}

	public String getPassword(String projectCode) {
		if(projectCode==null){
			//默认给主库连接
			projectCode = propDbProjectCode;
			dbPassword.put(propDbProjectCode, propDbPassword);
		}
		if (dbPassword.containsKey(projectCode)) {
			return dbPassword.get(projectCode);
		}
		return "";
	}


	private static class ProjectDBMgrBuilder {
		private static ProjectDBMgr instance = new ProjectDBMgr();
	}
}

读取配置文件工具类


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

public class PropUtils {
    private static Logger logger = LoggerFactory.getLogger(PropUtils.class);
    private static Properties properties;
    static {
        if (properties!=null) {
        }
        else {
            InputStream in = null;
            try {
                properties = new Properties();
                in = PropUtils.class.getClassLoader().getResourceAsStream("config.properties");
                BufferedReader br= new BufferedReader(new InputStreamReader(in));
                properties.load(br);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static  String  getProp(String key){
        return properties.getProperty(key);
    }
}


我的这张表是建在主库中的,表名url
dbname是数据库 名称,ip可以换成你要连接的数据库地址
dbname是数据库 名称,ip如其他地址,可以换成其他的IP
这里是我演示的三个库,库名就不展示了,用的是生产库
在这里插入图片描述
下面三个库分别存了一条数据
库2的一条数据
在这里插入图片描述
库3的一条数据
在这里插入图片描述
库1的一条数据
在这里插入图片描述

测试接口调用

@RequestMapping("/地址")
    @ResponseBody
    public String getTunnelList(@RequestParam(value="projectCode", required=true) String projectCode, String account, String dpuid) {
        try {
            //@RequestParam(value="projectCode", required=true) String projectCode,
            DBIdentifier.setProjectCode(projectCode);
            List<Tunnel> list = webService.getTunnelList(dpuid);
            //写入日志
            webService.writeLog(account, "获取数据列表", "操作成功");
            return JsonContent(new JsonResult(ResultType.SUCCESS.toString(), "操作成功", list));
        } catch (Exception e) {
        
        }
测试查询数据库2的数据

在这里插入图片描述

测试查询数据库1的数据

在这里插入图片描述

测试查询数据库3的数据在这里插入图片描述
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值