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 的复杂操作。

相关推荐
有梦想的攻城狮5 小时前
通过Lettuce实现PB3格式对象在Redis中的存储与查询
数据库·redis·缓存·pb3
小坏讲微服务5 小时前
Spring Boot整合Redis注解,实战Redis注解使用
spring boot·redis·分布式·后端·spring cloud·微服务·mybatis
xie_pin_an6 小时前
MyBatis-Plus 实战:MPJLambdaWrapper 多表联查用法全解析
java·spring boot·spring·mybatis
一个儒雅随和的男子6 小时前
多级缓存解决方案
spring boot·缓存
橘子海全栈攻城狮6 小时前
【源码+文档+调试讲解】基于Spring Boot的考务管理系统设计与实现 085
java·spring boot·后端·spring
⑩-6 小时前
Redis(1)
数据库·redis·缓存
東雪木9 小时前
Spring Boot 2.x 集成 Knife4j (OpenAPI 3) 完整操作指南
java·spring boot·后端·swagger·knife4j·java异常处理
陈果然DeepVersion10 小时前
Java大厂面试真题:从Spring Boot到AI微服务的三轮技术拷问(二)
spring boot·redis·spring cloud·微服务·ai·java面试·rag
Q_Q196328847510 小时前
python+django/flask的医院财务管理系统
spring boot·python·django·flask·node.js