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

相关推荐
zhougl9969 小时前
Java Spring Boot 爬虫技术全面介绍
java·spring boot·爬虫
xqqxqxxq10 小时前
Redis 五大常用数据类型 + 通用命令笔记
数据库·redis·笔记
用户31268748772012 小时前
@Async 加了没生效?Spring Boot 异步编程全链路拆解:从线程池到自调用陷阱
java·spring boot
云烟成雨TD14 小时前
Micrometer 系列【25】Spring Boot Actuator | Spring MVC、Spring WebFlux 指标
java·spring boot·micrometer
xbgRS14 小时前
springBoot项目配置加载优先级
java·spring boot
南城以南溫暖如初14715 小时前
社区健身小程序开发流程详解:技术选型与实施经验分享
java·经验分享·spring boot·mysql·vue·apache
vx-程序开发16 小时前
django汽车租赁系统---附源码25360
java·javascript·spring boot·python·eclipse·django·php
2601_9538246116 小时前
【计算机毕业设计】基于Spring Boot的宠物领养救助平台的设计与实现
spring boot·课程设计·宠物
LCG元16 小时前
ESP32-IDF 远程固件升级实战:HTTPS OTA + 双分区切换 + 自动回滚
数据库·redis·https
RuoyiOffice17 小时前
SpringBoot3+Vue3 会议室预订系统:时段冲突三模式检测 + 会前定时提醒与 cancelByBiz
spring boot·vue3·flowable·消息中心·spring boot 3·会议室·时段冲突