SpringBoot多数据源配置

  Druid 可以说是国内使用最广泛的数据源连接池产品


   com.alibaba
   druid-spring-boot-starter
   1.1.17

application.yml配置

spring:
  datasource:
    pay:
      username: root
      password: root
      host: 192.168.37.133:3306
      jdbc-url: jdbc:mysql://${spring.datasource.master.host}/${spring.datasource.master.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false
      schema-name: dlsms
    order:
      username: root
      password: root
      host: 192.168.37.134:3306
      jdbc-url: jdbc:mysql://${spring.datasource.slave.host}/${spring.datasource.slave.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false
      schema-name: dlsms

配置数据源和事务管理

import net.test.project.constants.DataSourceKey;

import com.alibaba.druid.pool.DruidDataSource;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
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.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;


@MapperScan({"net.test.project.dao.mapper.*"})
@Configuration
public class DataSourceProxyConfig {

	/**
	 * 配置默认数据源
	 * @return
	 */
    @Bean(name = "originOrder", initMethod = "init") // 声明其为Bean实例
	@ConfigurationProperties(prefix = "spring.datasource.order")
	public DataSource dataSourceMaster() {
		return new DruidDataSource();
	}

    @Bean(name = "originStorage", initMethod = "init") // 声明其为Bean实例
	@ConfigurationProperties(prefix = "spring.datasource.storage")
	public DataSource dataSourceStorage() {
		return new DruidDataSource();
	}

    @Bean(name = "originPay", initMethod = "init") // 声明其为Bean实例
	@ConfigurationProperties(prefix = "spring.datasource.pay")
	public DataSource dataSourcePay() {
		return new DruidDataSource();
	}

	/**
	 * 设置多数据源,配置动态路由数据源
	 * @return
	 */
	@Bean("dynamicDataSource")
	public DataSource dynamicDataSource(@Qualifier("originOrder") DataSource dataSourceOrder,
			@Qualifier("originStorage") DataSource dataSourceStorage,
			@Qualifier("originPay") DataSource dataSourcePay) {

		DynamicDataSource dynamicRoutingDataSource = new DynamicDataSource();

		Map dataSourceMap = new HashMap<>(3);
		dataSourceMap.put(DataSourceKey.ORDER.name(), dataSourceOrder);
		dataSourceMap.put(DataSourceKey.STORAGE.name(), dataSourceStorage);
		dataSourceMap.put(DataSourceKey.PAY.name(), dataSourcePay);
        //设置默认
		dynamicRoutingDataSource.setDefaultTargetDataSource(dataSourceOrder);
		dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);

		return dynamicRoutingDataSource;
	}

	/**
	 * 设置会话工厂
	 *
	 * @return
	 * @throws Exception
	 */
	@Bean(name="sqlSessionFactory")
	public SqlSessionFactoryBean sqlSessionFactoryBean(
			@Qualifier("dynamicDataSource") DataSource dataSource) {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		return sqlSessionFactoryBean;
	}

	/**
	 * 配置事务管理器
	 *
	 * @return
	 */
	@Bean(name = "transactionManager")
	public PlatformTransactionManager transactionManager(@Qualifier("originOrder") DataSource dataSourceOrder,
			@Qualifier("originStorage") DataSource dataSourceStorage,
			@Qualifier("originPay") DataSource dataSourcePay) {
		return new DataSourceTransactionManager(dynamicDataSource(dataSourceOrder, dataSourceStorage, dataSourcePay));
	}
}

实现选择目标数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {
    /**
     * 取得当前使用哪个数据源
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceType();
    }
}

切换数据源

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

/**
 * 数据源切换处理
 * 
 */
public class DynamicDataSourceContextHolder
{
    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);

    /**
     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
     *  所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
     */
    private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>();

    /**
     * 设置数据源的变量
     */
    public static void setDataSourceType(String dsType)
    {
        log.info("切换到{}数据源", dsType);
        CONTEXT_HOLDER.set(dsType);
    }

    /**
     * 获得数据源的变量
     */
    public static String getDataSourceType()
    {
        return CONTEXT_HOLDER.get();
    }

    /**
     * 清空数据源变量
     */
    public static void clearDataSourceType()
    {
        CONTEXT_HOLDER.remove();
    }
}

如何使用

DynamicDataSourceContextHolder.setDataSourceType(DataSourceKey.ORDER);

你可能感兴趣的:(spring,boot,后端,java)