Spring Data Redis:如何通过Repository动态定义Keyspace?
需要为Redis Repository存储的Person实体实现动态keyspace,最终生成的键格式为people:{accountID}:{id}(例如people:1234:e33bebb5-5fe2-47b8-8bb8-ef80950090e7)。尝试过给方法加@KeySpace注解但无效,想知道是否必须用RedisTemplate才能实现这种灵活性。
示例实体类:
@RedisHash /*("people")*/ public class Person { @Id private String id; @TimeToLive(unit = TimeUnit.MINUTES) private Long ttlMinutes = 60L; private String accountID; private String name; // getter、setter省略 }
不需要直接使用RedisTemplate,Spring Data Redis提供了KeyspaceResolver接口,通过自定义该接口的实现类,就能实现动态keyspace的需求。
步骤1:实现自定义KeyspaceResolver
创建类实现KeyspaceResolver,重写方法结合实体的accountID字段和固定前缀生成动态keyspace:
import org.springframework.data.redis.core.mapping.KeyspaceResolver; import org.springframework.data.redis.core.mapping.RedisPersistentEntity; public class DynamicPersonKeyspaceResolver implements KeyspaceResolver { private static final String BASE_KEYSPACE = "people"; @Override public String resolveKeyspace(RedisPersistentEntity<?> entity) { return BASE_KEYSPACE; } @Override public String resolveKeyspace(Object entity) { if (entity instanceof Person person) { return String.format("%s:%s", BASE_KEYSPACE, person.getAccountID()); } return BASE_KEYSPACE; } }
重点说明:第二个
resolveKeyspace(Object entity)方法会传入具体的实体对象,我们可以从中读取accountID来拼接动态keyspace,这是实现动态逻辑的核心。
步骤2:配置RedisMappingContext
将自定义的KeyspaceResolver注入到RedisMappingContext中,让Spring Data Redis使用它生成keyspace:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.mapping.RedisMappingContext; import org.springframework.data.redis.repository.configuration.EnableRedisRepositories; @Configuration @EnableRedisRepositories public class RedisConfig { @Bean public RedisMappingContext redisMappingContext() { RedisMappingContext mappingContext = new RedisMappingContext(); mappingContext.setKeyspaceResolver(new DynamicPersonKeyspaceResolver()); return mappingContext; } }
步骤3:调整Person类注解
去掉@RedisHash的固定参数,直接保留注解即可:
@RedisHash public class Person { // 原有字段和方法不变 }
验证效果
当通过Redis Repository保存Person对象时,生成的键会自动变为people:{accountID}:{id}的格式,完全符合需求。
你之前尝试的@KeySpace注解是Spring Cache体系下的方法级缓存注解,和Redis Repository的实体keyspace逻辑不相关,所以不会生效。
内容的提问来源于stack exchange,提问作者E-Riz

