SpringBoot集成Redis 灵活使用 TypedTuple 和 DefaultTypedTuple 实现 Redis ZSet 的复杂操作

以下是 Spring Boot 集成 Redis 中 TypedTupleDefaultTypedTuple 的详细使用说明,包含代码示例和场景说明:


1. 什么是 TypedTuple 和 DefaultTypedTuple?

  • TypedTuple<T> 接口

    定义了 Redis 中有序集合(ZSet)的元素结构,包含 元素值(value)分数(score)

    • T 表示元素的类型(如 String、自定义对象等)。
  • DefaultTypedTuple<T>
    TypedTuple 的实现类,用于创建包含元素和分数的元组对象,常用于 ZSet 的增删改查操作


2. 使用场景

TypedTuple 主要用于以下场景:

  1. 存储带分数的元素(如排行榜、优先级队列)。
  2. 获取元素时同时获取分数(如查询用户积分及排名)。
  3. 批量操作 ZSet(如添加多个元素并指定分数)。

3. Spring Boot 配置

3.1 添加依赖

pom.xml 中添加以下依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
</dependency>
3.2 配置 RedisTemplate
java 复制代码
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 设置键和值的序列化器
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        return template;
    }
}

4. TypedTuple 的核心操作

4.1 创建 TypedTuple 对象

通过 DefaultTypedTuple 构造函数创建:

java 复制代码
TypedTuple<String> tuple = new DefaultTypedTuple<>("Alice", 90.0); // 元素值为 "Alice",分数为90.0
4.2 添加元素到 ZSet
java 复制代码
// 添加单个元素
redisTemplate.opsForZSet().add("leaderboard", "Alice", 90.0);

// 或使用 TypedTuple 批量添加
redisTemplate.opsForZSet().add("leaderboard", 
    new DefaultTypedTuple<>("Alice", 90.0),
    new DefaultTypedTuple<>("Bob", 85.0));
4.3 获取元素和分数
java 复制代码
// 获取所有元素及其分数(按分数升序)
Set<ZSetOperations.TypedTuple<String>> tuples = redisTemplate.opsForZSet().reverseRangeWithScores("leaderboard", 0, -1);

for (TypedTuple<String> tuple : tuples) {
    String member = tuple.getValue(); // 元素值(如 "Alice")
    Double score = tuple.getScore(); // 分数(如 90.0)
    System.out.println("Member: " + member + ", Score: " + score);
}
4.4 更新元素分数
java 复制代码
// 更新元素的分数
redisTemplate.opsForZSet().add("leaderboard", "Alice", 95.0); // 若已存在,分数会被更新
4.5 删除元素
java 复制代码
// 删除指定元素
redisTemplate.opsForZSet().remove("leaderboard", "Alice");

5. 完整代码示例

5.1 服务类实现
java 复制代码
@Service
public class RankService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 添加用户到排行榜
    public void addUserToLeaderboard(String userId, double score) {
        redisTemplate.opsForZSet().add("leaderboard", userId, score);
    }

    // 获取前10名用户及其分数
    public List<ScoredUser> getTop10() {
        Set<ZSetOperations.TypedTuple<String>> tuples = 
            redisTemplate.opsForZSet().reverseRangeWithScores("leaderboard", 0, 9);

        List<ScoredUser> result = new ArrayList<>();
        for (TypedTuple<String> tuple : tuples) {
            ScoredUser user = new ScoredUser();
            user.setId(tuple.getValue());
            user.setScore(tuple.getScore());
            result.add(user);
        }
        return result;
    }

    // 自定义返回对象
    @Data
    private static class ScoredUser {
        private String id;
        private Double score;
    }
}
5.2 使用示例
java 复制代码
@Autowired
private RankService rankService;

// 添加用户
rankService.addUserToLeaderboard("user1001", 90.0);
rankService.addUserToLeaderboard("user1002", 85.0);

// 获取前10名
List<ScoredUser> top10 = rankService.getTop10();
for (ScoredUser user : top10) {
    System.out.println("ID: " + user.getId() + ", Score: " + user.getScore());
}

6. 关键代码说明

6.1 添加元素(带分数)
java 复制代码
// 直接添加元素和分数
redisTemplate.opsForZSet().add(key, member, score);

// 使用 TypedTuple 批量添加
redisTemplate.opsForZSet().add(key, 
    new DefaultTypedTuple<>("Alice", 90.0),
    new DefaultTypedTuple<>("Bob", 85.0));
6.2 获取元素和分数
java 复制代码
// 获取带分数的元素(按分数降序)
Set<ZSetOperations.TypedTuple<String>> tuples = 
    redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);

// 遍历获取每个元素和分数
for (TypedTuple<String> tuple : tuples) {
    String member = tuple.getValue();
    Double score = tuple.getScore();
}
6.3 更新元素分数
java 复制代码
// 若元素已存在,会更新其分数
redisTemplate.opsForZSet().add(key, member, newScore);

7. 总结表格

操作 方法 描述
添加元素 opsForZSet().add(key, member, score) 添加元素并指定分数。
批量添加 opsForZSet().add(key, tuples) 使用 TypedTuple 列表批量添加元素。
获取元素和分数 opsForZSet().reverseRangeWithScores(key, start, end) 获取指定范围的元素及其分数(按分数降序)。
更新分数 opsForZSet().add(key, member, newScore) 若元素已存在,更新其分数。
删除元素 opsForZSet().remove(key, member) 删除指定元素。

8. 注意事项

  1. 泛型类型

    • TypedTuple<T> 的类型 T 必须与 ZSet 中的元素类型一致(如 String、自定义对象等)。
    • 若存储自定义对象,需确保序列化配置正确(如使用 GenericJackson2JsonRedisSerializer)。
  2. 分数范围查询

    • 使用 rangeByScoreWithScores(key, min, max) 可根据分数范围获取元素。
  3. 性能优化

    • 大量数据操作时,优先使用批量操作(如 add 接受 TypedTuple 列表)。

通过以上示例和说明,可以灵活使用 TypedTupleDefaultTypedTuple 实现 Redis ZSet 的复杂操作。

相关推荐
KevinCyao7 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
總鑽風7 小时前
搭建Spring Boot + ELK日志平台,实现可视化日志监控
spring boot·elk·macos
不吃香菜学java8 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
新知图书8 小时前
搭建Spring Boot开发环境
java·spring boot·后端
皮皮林5518 小时前
SpringBoot 4 最被低估的新特性:Spring Data AOT
spring boot
宸津-代码粉碎机8 小时前
Spring Boot 4.0虚拟线程实战调优技巧,最大化发挥并发优势
java·人工智能·spring boot·后端·python
不知名的老吴8 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存
MaCa .BaKa8 小时前
47-心里健康咨询平台/心理咨询系统
java·spring boot·mysql·tomcat·maven·intellij-idea·个人开发
Devin~Y9 小时前
高并发电商与AI智能客服场景下的Java面试实战:从Spring Boot到RAG与向量数据库落地
java·spring boot·redis·elasticsearch·spring cloud·kafka·rag
磊 子9 小时前
redis详解2
java·spring boot·redis