从购物车到点赞排行:用Spring Boot RedisTemplate的opsForHash和opsForZSet搞定5个真实业务场景
从购物车到点赞排行用Spring Boot RedisTemplate的opsForHash和opsForZSet搞定5个真实业务场景Redis作为高性能的内存数据库在现代互联网应用中扮演着越来越重要的角色。特别是在高并发场景下合理利用Redis的数据结构可以显著提升系统性能。本文将基于Spring Boot框架通过RedisTemplate提供的opsForHash和opsForZSet等操作实现五个典型的业务场景。1. 用opsForHash实现购物车功能电商平台的购物车是一个典型的使用哈希表结构的场景。每个用户的购物车可以看作是一个哈希表其中商品ID作为字段(field)商品数量和属性作为值(value)。// 添加商品到购物车 public void addToCart(String userId, String productId, int quantity) { redisTemplate.opsForHash().put(cart: userId, productId, String.valueOf(quantity)); } // 获取购物车中某商品数量 public int getProductQuantity(String userId, String productId) { Object quantity redisTemplate.opsForHash().get(cart: userId, productId); return quantity ! null ? Integer.parseInt(quantity.toString()) : 0; } // 获取整个购物车内容 public MapObject, Object getCart(String userId) { return redisTemplate.opsForHash().entries(cart: userId); }哈希表结构的优势在于可以单独操作某个字段而不需要读取整个哈希表内存占用更高效特别适合存储对象类型的数据支持原子性操作保证数据一致性2. 用opsForZSet实现文章点赞排行榜内容平台的点赞排行是一个典型的排序需求有序集合(ZSet)可以完美解决这个问题。我们可以将文章ID作为成员(member)点赞数作为分数(score)。// 用户点赞文章 public void likeArticle(String articleId, String userId) { // 使用集合记录已点赞用户防止重复点赞 String likeKey article:liked: articleId; if (redisTemplate.opsForSet().add(likeKey, userId) 1) { // 点赞成功增加文章分数 redisTemplate.opsForZSet().incrementScore(article:ranking, articleId, 1); } } // 获取点赞排行榜前10 public SetZSetOperations.TypedTupleObject getTop10Articles() { return redisTemplate.opsForZSet().reverseRangeWithScores(article:ranking, 0, 9); }有序集合的特点自动按分数排序支持范围查询可以获取成员的排名支持分数增减操作3. 用opsForList实现最新评论列表对于内容平台的评论系统我们通常需要展示最新的评论。Redis的列表(List)结构可以很好地满足这个需求。// 添加新评论 public void addComment(String articleId, String commentId, String comment) { String key comments: articleId; // 将新评论添加到列表头部 redisTemplate.opsForList().leftPush(key, comment); // 限制列表长度只保留最近100条评论 redisTemplate.opsForList().trim(key, 0, 99); } // 获取最新10条评论 public ListObject getLatestComments(String articleId, int count) { return redisTemplate.opsForList().range(comments: articleId, 0, count - 1); }列表结构的优势插入和获取头部元素的时间复杂度都是O(1)支持范围查询可以方便地实现队列或栈的功能4. 用opsForSet实现共同关注/好友推荐社交网络中的共同关注和好友推荐功能可以利用Redis的集合(Set)结构来实现。// 用户关注某人 public void followUser(String userId, String followId) { redisTemplate.opsForSet().add(following: userId, followId); redisTemplate.opsForSet().add(followers: followId, userId); } // 获取共同关注 public SetObject getCommonFollowing(String userId1, String userId2) { return redisTemplate.opsForSet().intersect( following: userId1, following: userId2 ); } // 推荐可能认识的人(共同关注最多的人) public SetObject recommendFriends(String userId) { // 获取用户关注的人 SetObject following redisTemplate.opsForSet().members(following: userId); // 获取这些人的关注列表 ListString otherKeys following.stream() .map(f - following: f) .collect(Collectors.toList()); // 计算这些关注列表与当前用户关注列表的交集 return redisTemplate.opsForSet().intersect( following: userId, otherKeys ); }集合结构的特点自动去重支持集合运算(并集、交集、差集)可以快速判断元素是否存在5. 用opsForValue实现分布式锁和验证码缓存Redis的字符串(String)结构虽然简单但在实际应用中非常有用比如实现分布式锁和验证码缓存。// 获取分布式锁 public boolean tryLock(String lockKey, String requestId, long expireTime) { return redisTemplate.opsForValue().setIfAbsent( lockKey, requestId, expireTime, TimeUnit.MILLISECONDS ); } // 释放分布式锁 public boolean releaseLock(String lockKey, String requestId) { String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; return redisTemplate.execute( new DefaultRedisScript(script, Long.class), Collections.singletonList(lockKey), requestId ) 1; } // 存储验证码 public void storeCaptcha(String phone, String captcha) { String key captcha: phone; redisTemplate.opsForValue().set(key, captcha, 5, TimeUnit.MINUTES); } // 验证验证码 public boolean verifyCaptcha(String phone, String inputCaptcha) { String key captcha: phone; String storedCaptcha (String) redisTemplate.opsForValue().get(key); return inputCaptcha ! null inputCaptcha.equals(storedCaptcha); }字符串结构的使用技巧可以设置过期时间适合临时数据存储操作简单高效支持原子性操作在实际项目中选择合适的数据结构需要考虑以下因素数据的访问模式(读多还是写多)是否需要排序是否需要去重数据量大小是否需要设置过期时间RedisTemplate提供了丰富的操作方法但要注意序列化问题。建议根据业务需求配置合适的序列化方式避免出现类型转换错误。