SpringBoot配置mysql redis多数据源

Mysql配置多数据源

从AbstractRoutingDataSource中需求解决方案
	@Override
	//获取数据库连接
	public Connection getConnection() throws SQLException {
		return determineTargetDataSource().getConnection();
	}
	@Nullable
	//保存的是数据源map字典
	private Map<Object, DataSource> resolvedDataSources;
	/**
	*获取数据源逻辑
	*/
	protected DataSource determineTargetDataSource() {
		Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
		//拿到数据源对应的字典key
		Object lookupKey = determineCurrentLookupKey();
		//从字典中获取数据源
		DataSource dataSource = this.resolvedDataSources.get(lookupKey);
		if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
			//如果key为空就使用默认数据源
			dataSource = this.resolvedDefaultDataSource;
		}
		if (dataSource == null) {
			throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
		}
		return dataSource;
	}
	//获取数据源key 空实现,那么我们就可以自己去实现该逻辑,然后
	//把该动态数据源设置给spring容器
	@Nullable
	protected abstract Object determineCurrentLookupKey();
配置我们的动态数据源
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
	//存放数据源key的ThreadLocal
    private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<DatabaseType>();

    @Override
    //获取数据源的时候从ThreadLocal去取要用的key
    protected Object determineCurrentLookupKey() {
        return contextHolder.get();
    }

    public static void setDb1() {
        contextHolder.set(DatabaseType.DB1);
    }

    public static void setDb2() {
        contextHolder.set(DatabaseType.DB2);
    }
    public static void setDatabaseType(DatabaseType type) {
        log.info("setDatabaseType:{}",type.name());
        contextHolder.set(type);
    }

    public static DatabaseType getType() {
        return contextHolder.get();
    }
    public static enum DatabaseType {
        DB1, DB2
    }
}
配置两个数据源对象
@Configuration
public class DataSourceConf {
    public DataSourceConf(){
    }

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

    @Bean
    //利用ConfigurationProperties给ConfigurationProperties设置属性
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource db2(){
        return new DruidDataSource();
    }

    @Autowired
    //用@Primary 告诉spring 存在多个实现对象时候选择哪一个具体
    @Primary
    //利用我们自己的动态数据源替换掉sparingboot自动创建的dataSource
    //配合@Primary让springboot优先使用该数据源
    @Bean("dataSource")
    //@Qualifier("db1") 存在多个DataSource具体注入哪个,按照name来注入
    public DynamicDataSource dynamicDataSource(@Qualifier("db1") DataSource db1,@Qualifier("db2") DataSource db2) {
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        targetDataSources.put(DynamicDataSource.DatabaseType.DB1, db1);
        targetDataSources.put(DynamicDataSource.DatabaseType.DB2, db2);
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
        dataSource.setDefaultTargetDataSource(db1);
        return dataSource;
    }
}
配置切面
@Aspect
@Component
@Slf4j
public class DataSourceAOP {
	//配置不同的包下的mapper使用不同的数据源
	//如果要读写分离,也可以把切入点表达式配置到方法名级别
	//例如insert* update* 走写库 其他的走读库
    @Before("execution(* com.xxxx.dao.db1.*.*(..))")
    public void setDB1DataSourceType(JoinPoint point) {
        DynamicDataSource.setDb1();
        log.info("dataSource切换到:db1");
    }

    @Before("execution(* com.xxxx.dao.db2.*.*(..))")
    public void setDB2DataSourceType(JoinPoint point) {
        DynamicDataSource.setDb2();
        log.info("dataSource切换到:db2");
    }
}
配置文件
spring.datasource.db1.url=jdbc:mysql://xxx:3306/db1?zeroDateTimeBehavior=convertToNull
spring.datasource.db1.username=xxx
spring.datasource.db1.password=xxx
spring.datasource.db1.initial-size=20
spring.datasource.db1.max-active=100
spring.datasource.db1.min-idle=20
spring.datasource.db1.max-wait=2000
spring.datasource.db1.stat-view-servlet.login-username=admin
spring.datasource.db1.stat-view-servlet.login-password=admin

#mix
spring.datasource.db2.url=jdbc:mysql://xxx/db2?zeroDateTimeBehavior=convertToNull
spring.datasource.db2.username=xxx
spring.datasource.db2.password=xxx
spring.datasource.db2.initial-size=20
spring.datasource.db2.max-active=100
spring.datasource.db2.min-idle=20
spring.datasource.db2.max-wait=2000
spring.datasource.db2.stat-view-servlet.login-username=admin
spring.datasource.db2.stat-view-servlet.login-password=admin

Redis多数据源

配置文件
# redis setting
spring.redis.host=xxx
spring.redis.port=6379
spring.redis.database=0
spring.redis.jedis.pool.max-idle=200
spring.redis.jedis.pool.max-wait=5000

# redis setting
spring.redis.other.host=xxx
spring.redis.other.port=6379
spring.redis.other.database=0
spring.redis.other.jedis.pool.max-idle=200
spring.redis.other.jedis.pool.max-total=500
spring.redis.other.jedis.pool.max-wait=5000
配置redisTemplate
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * RedisTemplate配置
     */
    @Bean("mainRedisTemplate")
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(stringRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}
package com.ttyc.ebike.config.redis;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class OtherRedisConfig {

    @Value("${spring.redis.other.host}")
    private String otherHost;
    @Value("${spring.redis.other.port}")
    private Integer otherPort;
    @Value("${spring.redis.other.jedis.pool.max-idle}")
    private Integer otherMaxIdle;
    @Value("${spring.redis.other.jedis.pool.max-total}")
    private Integer otherMaxTotal;
    @Value("${spring.redis.other.jedis.pool.max-wait}")
    private Integer otherMaxWaitMillis;
    @Value("${spring.redis.other.database}")
    private Integer otherDataBase;

    //配置工厂
    public RedisConnectionFactory connectionFactory(String host, int port, String password, int maxIdle,
                                                    int maxTotal, long maxWaitMillis, int index) {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setHostName(host);
        jedisConnectionFactory.setPort(port);
        if (!StringUtils.isEmpty(password)) {
            jedisConnectionFactory.setPassword(password);
        }
        if (index != 0) {
            jedisConnectionFactory.setDatabase(index);
        }
		jedisConnectionFactory.setPoolConfig(poolConfig(maxIdle, maxTotal, maxWaitMillis, false));
        jedisConnectionFactory.afterPropertiesSet();
        return jedisConnectionFactory;
    }

    //连接池配置
    public JedisPoolConfig poolConfig(int maxIdle, int maxTotal, long maxWaitMillis, boolean testOnBorrow) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxWaitMillis(maxWaitMillis);
        poolConfig.setTestOnBorrow(testOnBorrow);
        return poolConfig;
    }

    @Bean(name = "otherRedisTemplate")
    public StringRedisTemplate redisOrderTemplate() {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(
                connectionFactory(otherHost, otherPort, "", otherMaxIdle, otherMaxTotal, otherMaxWaitMillis, otherDataBase));
        return template;
    }

使用
    @Autowired
    //按照name注入
    @Qualifier("otherRedisTemplate")
    protected RedisTemplate<String, String> aiRedisTemplate;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值