|
|
同一个 Redis 实例里要用多个 DB,比如应用平时用 `database:0`,但要删除的数据在 `database:1`,需要在 Spring Boot 里同时访问 0 和 1 两个库。
- 创建 **多个 `RedisConnectionFactory` / `RedisTemplate`**,每个绑定一个不同的 `database`。
- 平时业务用默认的(db0),清理数据时用专门指向 db1 的模板。
下面给出一个常见实现方式(基于 Lettuce,Spring Boot 2.x 默认)。
---
**1. application.yml 中仍然只配置一个 Redis 节点**
Redis 本身就是一个节点,DB 只是编号,不需要写多份 IP/端口:
```yaml
spring:
redis:
host: 127.0.0.1
port: 6379
password: 123456
database: 0 # 默认 DB,仍然是 0
lettuce:
pool:
max-active: 32
max-idle: 16
min-idle: 0
max-wait: 3s
```
> 说明:我们在 Java 配置里额外创建一个专门指向 `database:1` 的工厂/模板。
---
**2. Java 配置:为不同 DB 建不同的 `StringRedisTemplate`**
新建一个配置类,比如 `RedisConfig.java`:
```java
package com.example.sms.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
// 默认的 StringRedisTemplate(使用 spring.redis.database,通常是 0)
// Spring Boot 已经自动配置了一个,你可以继续用现成的。
// DB1 的连接工厂
@Bean
public LettuceConnectionFactory redisConnectionFactoryDb1() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
if (password != null && !password.isEmpty()) {
config.setPassword(RedisPassword.of(password));
}
config.setDatabase(1); // 关键:指定使用 DB 1
return new LettuceConnectionFactory(config);
}
// 指向 DB1 的 StringRedisTemplate
@Bean
public StringRedisTemplate stringRedisTemplateDb1() {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactoryDb1());
return template;
}
}
```
要点:
- 默认的 `spring.redis.database` 仍是 0,Spring Boot 会帮你创建一个默认的 `StringRedisTemplate`(你现在 `SmsServiceImpl` 里注入的就是它)。
- 我们自己再创建一个 `redisConnectionFactoryDb1`,只改 `setDatabase(1)`。
- 再基于它创建一个 `StringRedisTemplate` Bean(例如叫 `stringRedisTemplateDb1`)。
---
**3. 在代码中使用不同 DB 的模板**
- 业务代码继续用默认 DB0 的 `StringRedisTemplate`:
```java
@Autowired
private StringRedisTemplate redisTemplate; // 指向 database:0
```
- 要操作 DB1 的时候,注入我们刚才配置的那个:
```java
@Autowired
private StringRedisTemplate stringRedisTemplateDb1; // 指向 database:1
```
示例:删除 `database:1` 中前缀为 `sms:` 的数据:
```java
@Service
public class RedisDb1CleanupService {
@Autowired
private StringRedisTemplate stringRedisTemplateDb1;
public void deleteSmsKeysInDb1() {
// 简单版(key 不多时)
Set<String> keys = stringRedisTemplateDb1.keys("sms:*");
if (keys != null && !keys.isEmpty()) {
stringRedisTemplateDb1.delete(keys);
}
}
}
```
如果数据量大,就结合前面说的 SCAN 分批删除,只是把 `redisTemplate` 换成 `stringRedisTemplateDb1` 即可。
---
**4. 总结用法**
- `database:0`:继续用原来的 `StringRedisTemplate`。
- `database:1`:在配置类里手工创建一个指向 DB1 的 `LettuceConnectionFactory` 和 `StringRedisTemplate`,需要访问 DB1 时注入并使用它。
|
|