在项目开发中我们可能会使用到多个Redis数据源,在该项目中也做了多数据源的实现,并且每个数据源都可以动态的切换db进行操作。并且完全基于springboot自动配置流程开发,生产项目中使用无风险。

源码和使用案例https://gitee.com/mr_wenpan/basis-enhance

1、应用启动类上使用注解开启多数据源使用

@SpringBootApplication
@EnableConfigurationProperties
// 开启redis多数据源使用
@EnableRedisMultiDataSource
public class EnhanceDataRedisDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(EnhanceDataRedisDemoApplication.class, args);
    }

}

2、application.yml配置配置多数据源

spring:
  application:
    name: enhance-data-redis-demo
  redis:
    # 默认数据源
    host: ${SPRING_REDIS_HOST:default-host}
    port: ${SPRING_REDIS_PORT:6379}
    password: ${SPRING_REDIS_PASSWORD:WenPan@123}
    database: ${SPRING_REDIS_DATABASE:0}
    client-type: lettuce
    lettuce:
      pool:
        max-active: ${SPRING_REDIS_POOL_MAX_ACTIVE:16}
        max-idle: ${SPRING_REDIS_POOL_MAX_IDLE:16}
        max-wait: ${SPRING_REDIS_POOL_MAX_WAIT:5000}
    datasource:
      # 第一个数据源
      source1:
        host: ${SPRING_REDIS_HOST:wenpan-host}
        port: ${SPRING_REDIS_PORT:6379}
        password: ${SPRING_REDIS_PASSWORD:WenPan@123}
        database: ${SPRING_REDIS_DATABASE:1}
      # 第二个数据源
      source2:
        host: ${SPRING_REDIS_HOST:yuanping-host}
        port: ${SPRING_REDIS_PORT:6379}
        password: ${SPRING_REDIS_PASSWORD:WenPan@123}
        database: ${SPRING_REDIS_DATABASE:2}
        
stone:
  redis:
  	# 开启多数据源动态切换redis db
    dynamic-database: true

3、使用默认的数据源

操作默认数据源,直接注入RedisHelper即可。

使用方式一

@Slf4j
@RestController("TestEncryptController.v1")
@RequestMapping("/v1/test-enhance-redis")
public class TestEnhanceDataRedisController {

    /**
     * 注入默认数据源的redisTemplate
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
  
  	/**
     * 默认数据源对应的redisHelper
     */
    @Autowired
    @Qualifier("redisHelper")
    private RedisHelper redisHelper;
 
  	@GetMapping("/test-default")
    public void testDefaultRedisTemplate() {
        // 使用默认数据源的redisTemplate操作默认数据源
        redisTemplate.opsForValue().set("key", "value");
      	// 使用默认数据源的redisHelper操作默认数据源
        redisHelper.lstRightPop("key");
      
      	// 使用默认数据源的redisHelper动态切换db
        try {
            redisHelper.setCurrentDatabase(2);
            redisHelper.lstRightPop("key");
        } finally {
            redisHelper.clearCurrentDatabase();
        }
    }
  
}

使用方式二(更优雅的使用)

// 多数据源情况下,操作默认数据源并动态切换db测试
@GetMapping("/test-100")
public void test100() {
    // 使用多数据源客户端操作默认数据源的指定db
    
    // 操作默认的数据源的1号db
    multisourceClient.opsDbOne(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());
    // 操作默认的数据源的2号db
    multisourceClient.opsDbTwo(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());
    // 操作默认的数据源的3号db
    multisourceClient.opsDbThree(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());

    // 使用redisHelper操作默认数据源的指定db
    
    // 操作默认的数据源的1号db
    redisHelper.opsDbOne().opsForValue().get("key");
    // 操作默认的数据源的2号db
    redisHelper.opsDbTwo().opsForValue().get("key");

}

4、使用指定的数据源

使用方式一

①、指定数据源名称注入指定的数据源

@Slf4j
@RestController("TestEncryptController.v1")
@RequestMapping("/v1/test-enhance-redis")
public class TestEnhanceDataRedisController {

  	/**
     * 注入第一个数据源
     */
    @Autowired
    @Qualifier("source1RedisTemplate")
    private RedisTemplate<String, String> source1RedisTemplate;
  
  	/**
     * source1数据源对应的redisHelper
     */
    @Autowired
    @Qualifier("source1RedisHelper")
    private RedisHelper source1RedisHelper;
  
  	@GetMapping("/test-source1-template")
    public void testSource1RedisTemplate() {
        // 使用source1数据源的redisTemplate操作source1数据源
        source1RedisTemplate.opsForValue().set("key", "value");
      	// 使用source1数据源的redisHelper操作source1数据源(切换db操作)
         EasyRedisHelper.execute(2, () -> source1RedisHelper.lstLeftPush("key", "value"));
    }
}

使用方式二(更简单的使用)

以上使用方式一使用起来都较为复杂,不是特别友好(比如:我们需要手动的使用@Qualifier注解指定容器中bean的名称进行注入),这里提供一种更加友好的使用方式RedisMultisourceClient,在RedisMultisourceClient中提供了丰富的易用的对于多数据源和动态切换db的操作。

@Slf4j
@RestController("TestMultiDataSourceController.v1")
@RequestMapping("/v1/test-multi-source")
public class TestMultiDataSourceController {

    @Autowired
    private RedisMultisourceClient multisourceClient;
  
   	@Autowired
    private RedisHelper redisHelper;
  
  	/**
  	 * 操作指定的数据源的指定db
  	 */
    @GetMapping("/test-1")
    public void test01() {
        String key = "test-" + UUID.randomUUID().toString();
        String value = "value-" + UUID.randomUUID().toString();
        log.info("key = {}, value = {}", key, value);
      	// 写入source1数据源的1号库
        multisourceClient.opsDbOne("source1").opsForValue().set(key, value);
     	  // 写入source2数据源的1号库
      	multisourceClient.opsDbOne("source2").opsForValue().set(key, value);
      
      	// 写入source1数据源的2号库
        multisourceClient.opsDbOne("source1").opsForValue().set(key, value);
     	  // 写入source2数据源的2号库
      	multisourceClient.opsDbOne("source2").opsForValue().set(key, value);
    }
  
  	/**
     * 操作默认数据源的指定db
     */
    @GetMapping("/test-01")
    public void test01() {
        // 操作1号db
        redisHelper.opsDbOne().opsForValue().set(getRandomValue(), getRandomValue());
        // 操作2号db
        redisHelper.opsDbTwo().opsForValue().set(getRandomValue(), getRandomValue());
        // 操作3号db
        redisHelper.opsDbThree().opsForValue().set(getRandomValue(), getRandomValue());
        // 操作4号db
        redisHelper.opsDbFour().opsForValue().set(getRandomValue(), getRandomValue());
    }
  
  	/**
     * 使用多数据源客户端操作默认数据源并且动态切换db
     */
  	@GetMapping("/test-100")
    public void test100() {
        // 操作默认的数据源的1号db
        multisourceClient.opsDbOne(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());
        // 操作默认的数据源的2号db
        multisourceClient.opsDbTwo(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());
        // 操作默认的数据源的3号db
        multisourceClient.opsDbThree(DEFAULT_SOURCE).opsForValue().set(getRandomValue(), getRandomValue());
    }
}