RedisTemplate在Spring Boot中的五种数据结构全面详解

发布于:2025-07-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

📋目录

🔧 环境配置

1. 添加依赖

2. 配置文件

3. Redis配置类

📝 String(字符串)- 完整操作

🎯 特点和使用场景

💡 完整操作API

🌟 String类型实际应用示例

📋 List(列表)- 完整操作

🎯 特点和使用场景

💡 完整操作API

🌟 List类型实际应用示例

🔧 Set(集合)- 完整操作

🎯 特点和使用场景

💡 完整操作API

🌟 Set类型实际应用示例

🗂️ Hash(哈希)- 完整操作

🎯 特点和使用场景

💡 完整操作API

🌟 Hash类型实际应用示例

🏆 ZSet(有序集合)- 完整操作

🎯 特点和使用场景

💡 完整操作API

🌟 ZSet类型实际应用示例

🔑 通用Key操作

完整的Key管理操作

⚡ 高级特性

1. 事务操作

2. 流水线操作

3. Lua脚本操作

4. 发布订阅

🚀 实战示例

完整的电商系统Redis应用

📝 最佳实践总结

1. 性能优化建议

2. 数据结构选择指南

3. 常见问题解决

4. 监控和运维

🎯 总结

🌟 核心特性

📚 学习路径建议

🛠️ 开发建议


🔧 环境配置

1. 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. 配置文件

spring:
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 200
        max-idle: 20
        min-idle: 5
        max-wait: -1ms

3. Redis配置类

@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());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        
        template.afterPropertiesSet();
        return template;
    }
}

📝 String(字符串)- 完整操作

🎯 特点和使用场景

  • 特点:最基础的数据类型,二进制安全,最大512MB
  • 使用场景:缓存、计数器、分布式锁、会话存储、限流

💡 完整操作API

@Service
public class StringRedisService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // ============ 基本存取操作 ============
    
    /**
     * 设置键值对
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }
    
    /**
     * 设置键值对并指定过期时间
     */
    public void setWithExpire(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }
    
    /**
     * 只有键不存在时才设置(原子操作)
     */
    public Boolean setIfAbsent(String key, Object value) {
        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }
    
    /**
     * 只有键不存在时才设置,并指定过期时间
     */
    public Boolean setIfAbsent(String key, Object value, long timeout, TimeUnit unit) {
        return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
    }
    
    /**
     * 只有键存在时才设置
     */
    public Boolean setIfPresent(String key, Object value) {
        return redisTemplate.opsForValue().setIfPresent(key, value);
    }
    
    /**
     * 只有键存在时才设置,并指定过期时间
     */
    public Boolean setIfPresent(String key, Object value, long timeout, TimeUnit unit) {
        return redisTemplate.opsForValue().setIfPresent(key, value, timeout, unit);
    }
    
    /**
     * 获取值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
    
    /**
     * 设置新值并返回旧值
     */
    public Object getAndSet(String key, Object value) {
        return redisTemplate.opsForValue().getAndSet(key, value);
    }
    
    /**
     * 获取键的子字符串
     */
    public String getRange(String key, long start, long end) {
        return redisTemplate.opsForValue().get(key, start, end);
    }
    
    /**
     * 从指定位置开始设置值
     */
    public void setRange(String key, Object value, long offset) {
        redisTemplate.opsForValue().set(key, value, offset);
    }
    
    // ============ 批量操作 ============
    
    /**
     * 批量设置多个键值对
     */
    public void multiSet(Map<String, Object> map) {
        redisTemplate.opsForValue().multiSet(map);
    }
    
    /**
     * 批量设置多个键值对(仅当所有键都不存在时)
     */
    public Boolean multiSetIfAbsent(Map<String, Object> map) {
        return redisTemplate.opsForValue().multiSetIfAbsent(map);
    }
    
    /**
     * 批量获取多个键的值
     */
    public List<Object> multiGet(Collection<String> keys) {
        return redisTemplate.opsForValue().multiGet(keys);
    }
    
    // ============ 数字操作 ============
    
    /**
     * 自增1
     */
    public Long increment(String key) {
        return redisTemplate.opsForValue().increment(key);
    }
    
    /**
     * 自增指定值
     */
    public Long increment(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }
    
    /**
     * 自增指定浮点数值
     */
    public Double increment(String key, double delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }
    
    /**
     * 自减1
     */
    public Long decrement(String key) {
        return redisTemplate.opsForValue().decrement(key);
    }
    
    /**
     * 自减指定值
     */
    public Long decrement(String key, long delta) {
        return redisTemplate.opsForValue().decrement(key, delta);
    }
    
    // ============ 字符串操作 ============
    
    /**
     * 追加字符串到末尾
     */
    public Integer append(String key, String value) {
        return redisTemplate.opsForValue().append(key, value);
    }
    
    /**
     * 获取字符串长度
     */
    public Long size(String key) {
        return redisTemplate.opsForValue().size(key);
    }
    
    /**
     * 设置bit位的值
     */
    public Boolean setBit(String key, long offset, boolean value) {
        return redisTemplate.opsForValue().setBit(key, offset, value);
    }
    
    /**
     * 获取bit位的值
     */
    public Boolean getBit(String key, long offset) {
        return redisTemplate.opsForValue().getBit(key, offset);
    }
    
    /**
     * 统计bit位为1的个数
     */
    public Long bitCount(String key) {
        return redisTemplate.opsForValue().bitCount(key);
    }
    
    /**
     * 统计指定范围内bit位为1的个数
     */
    public Long bitCount(String key, long start, long end) {
        return redisTemplate.opsForValue().bitCount(key, start, end);
    }
}

🌟 String类型实际应用示例

// 分布式锁实现
public boolean tryLock(String lockKey, String requestId, int expireTime) {
    return redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.SECONDS);
}

// 用户登录次数限制
public boolean isLoginAllowed(String userId) {
    String key = "login:count:" + userId;
    Long count = redisTemplate.opsForValue().increment(key);
    if (count == 1) {
        redisTemplate.expire(key, 24, TimeUnit.HOURS); // 24小时后重置
    }
    return count <= 5; // 最多5次
}

// 接口限流
public boolean isRequestAllowed(String apiKey, int limit, int windowSeconds) {
    String key = "rate:limit:" + apiKey + ":" + (System.currentTimeMillis() / 1000 / windowSeconds);
    Long count = redisTemplate.opsForValue().increment(key);
    if (count == 1) {
        redisTemplate.expire(key, windowSeconds, TimeUnit.SECONDS);
    }
    return count <= limit;
}

// 全局唯一ID生成
public long generateId(String businessType) {
    String key = "global:id:" + businessType;
    return redisTemplate.opsForValue().increment(key);
}

📋 List(列表)- 完整操作

🎯 特点和使用场景

  • 特点:有序、可重复、双端操作、支持阻塞操作
  • 使用场景:消息队列、最新动态、排行榜历史、任务队列

💡 完整操作API

@Service
public class ListRedisService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // ============ 插入操作 ============
    
    /**
     * 从左边插入单个元素
     */
    public Long leftPush(String key, Object value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }
    
    /**
     * 从左边插入多个元素
     */
    public Long leftPushAll(String key, Object... values) {
        return redisTemplate.opsForList().leftPushAll(key, values);
    }
    
    /**
     * 从左边插入集合中的所有元素
     */
    public Long leftPushAll(String key, Collection<Object> values) {
        return redisTemplate.opsForList().leftPushAll(key, values);
    }
    
    /**
     * 仅当列表存在时从左边插入
     */
    public Long leftPushIfPresent(String key, Object value) {
        return redisTemplate.opsForList().leftPushIfPresent(key, value);
    }
    
    /**
     * 在指定元素前面插入新元素
     */
    public Long leftPush(String key, Object pivot, Object value) {
        return redisTemplate.opsForList().leftPush(key, pivot, value);
    }
    
    /**
     * 从右边插入单个元素
     */
    public Long rightPush(String key, Object value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }
    
    /**
     * 从右边插入多个元素
     */
    public Long rightPushAll(String key, Object... values) {
        return redisTemplate.opsForList().rightPushAll(key, values);
    }
    
    /**
     * 从右边插入集合中的所有元素
     */
    public Long rightPushAll(String key, Collection<Object> values) {
        return redisTemplate.opsForList().rightPushAll(key, values);
    }
    
    /**
     * 仅当列表存在时从右边插入
     */
    public Long rightPushIfPresent(String key, Object value) {
        return redisTemplate.opsForList().rightPushIfPresent(key, value);
    }
    
    /**
     * 在指定元素后面插入新元素
     */
    public Long rightPush(String key, Object pivot, Object value) {
        return redisTemplate.opsForList().rightPush(key, pivot, value);
    }
    
    // ============ 弹出操作 ============
    
    /**
     * 从左边弹出元素
     */
    public Object leftPop(String key) {
        return redisTemplate.opsForList().leftPop(key);
    }
    
    /**
     * 从左边弹出元素,带超时(阻塞操作)
     */
    public Object leftPop(String key, long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().leftPop(key, timeout, unit);
    }
    
    /**
     * 从右边弹出元素
     */
    public Object rightPop(String key) {
        return redisTemplate.opsForList().rightPop(key);
    }
    
    /**
     * 从右边弹出元素,带超时(阻塞操作)
     */
    public Object rightPop(String key, long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().rightPop(key, timeout, unit);
    }
    
    /**
     * 从源列表右边弹出元素并插入到目标列表左边
     */
    public Object rightPopAndLeftPush(String sourceKey, String destinationKey) {
        return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey);
    }
    
    /**
     * 从源列表右边弹出元素并插入到目标列表左边(阻塞操作)
     */
    public Object rightPopAndLeftPush(String sourceKey, String destinationKey, long timeout, TimeUnit unit) {
        return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit);
    }
    
    // ============ 查询操作 ============
    
    /**
     * 获取列表长度
     */
    public Long size(String key) {
        return redisTemplate.opsForList().size(key);
    }
    
    /**
     * 根据索引获取元素
     */
    public Object index(String key, long index) {
        return redisTemplate.opsForList().index(key, index);
    }
    
    /**
     * 获取指定范围的元素
     */
    public List<Object> range(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }
    
    /**
     * 获取所有元素
     */
    public List<Object> getAllElements(String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }
    
    // ============ 修改操作 ============
    
    /**
     * 根据索引设置元素值
     */
    public void set(String key, long index, Object value) {
        redisTemplate.opsForList().set(key, index, value);
    }
    
    /**
     * 移除指定数量的指定值元素
     * count > 0: 从头向尾移除
     * count < 0: 从尾向头移除
     * count = 0: 移除所有
     */
    public Long remove(String key, long count, Object value) {
        return redisTemplate.opsForList().remove(key, count, value);
    }
    
    /**
     * 保留指定范围的元素,删除其他元素
     */
    public void trim(String key, long start, long end) {
        redisTemplate.opsForList().trim(key, start, end);
    }
}

🌟 List类型实际应用示例

// 用户消息队列
public void sendMessage(String userId, Message message) {
    String key = "user:messages:" + userId;
    redisTemplate.opsForList().leftPush(key, message);
    // 只保留最新1000条消息
    redisTemplate.opsForList().trim(key, 0, 999);
}

// 获取用户未读消息
public List<Object> getUnreadMessages(String userId, int count) {
    String key = "user:messages:" + userId;
    List<Object> messages = redisTemplate.opsForList().range(key, 0, count - 1);
    // 标记为已读(移除)
    for (int i = 0; i < messages.size(); i++) {
        redisTemplate.opsForList().rightPop(key);
    }
    return messages;
}

// 分布式任务队列
public void addTask(Task task) {
    String key = "task:queue";
    redisTemplate.opsForList().leftPush(key, task);
}

public Task getTask(long timeoutSeconds) {
    String key = "task:queue";
    return (Task) redisTemplate.opsForList().rightPop(key, timeoutSeconds, TimeUnit.SECONDS);
}

// 用户浏览历史
public void addBrowseHistory(String userId, String productId) {
    String key = "user:browse:" + userId;
    // 先移除已存在的记录
    redisTemplate.opsForList().remove(key, 0, productId);
    // 添加到最前面
    redisTemplate.opsForList().leftPush(key, productId);
    // 只保留最近50个浏览记录
    redisTemplate.opsForList().trim(key, 0, 49);
}

🔧 Set(集合)- 完整操作

🎯 特点和使用场景

  • 特点:无序、不重复、支持集合运算
  • 使用场景:标签系统、好友关系、权限管理、去重、抽奖

💡 完整操作API

@Service
public class SetRedisService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // ============ 基本操作 ============
    
    /**
     * 添加一个或多个元素
     */
    public Long add(String key, Object... values) {
        return redisTemplate.opsForSet().add(key, values);
    }
    
    /**
     * 移除一个或多个元素
     */
    public Long remove(String key, Object... values) {
        return redisTemplate.opsForSet().remove(key, values);
    }
    
    /**
     * 移除并返回一个随机元素
     */
    public Object pop(String key) {
        return redisTemplate.opsForSet().pop(key);
    }
    
    /**
     * 移除并返回多个随机元素
     */
    public List<Object> pop(String key, long count) {
        return redisTemplate.opsForSet().pop(key, count);
    }
    
    /**
     * 将元素从源集合移动到目标集合
     */
    public Boolean move(String key, Object value, String destKey) {
        return redisTemplate.opsForSet().move(key, value, destKey);
    }
    
    // ============ 查询操作 ============
    
    /**
     * 获取集合大小
     */
    public Long size(String key) {
        return redisTemplate.opsForSet().size(key);
    }
    
    /**
     * 判断元素是否在集合中
     */
    public Boolean isMember(String key, Object value) {
        return redisTemplate.opsForSet().isMember(key, value);
    }
    
    /**
     * 批量判断元素是否在集合中
     */
    public Map<Object, Boolean> isMember(String key, Object... values) {
        return redisTemplate.opsForSet().isMember(key, values);
    }
    
    /**
     * 获取所有元素
     */
    public Set<Object> members(String key) {
        return redisTemplate.opsForSet().members(key);
    }
    
    /**
     * 随机获取一个元素(不删除)
     */
    public Object randomMember(String key) {
        return redisTemplate.opsForSet().randomMember(key);
    }
    
    /**
     * 随机获取指定数量的元素(不删除)
     */
    public List<Object> randomMembers(String key, long count) {
        return redisTemplate.opsForSet().randomMembers(key, count);
    }
    
    /**
     * 随机获取指定数量的不重复元素(不删除)
     */
    public Set<Object> distinctRandomMembers(String key, long count) {
        return redisTemplate.opsForSet().distinctRandomMembers(key, count);
    }
    
    /**
     * 遍历集合(支持模式匹配)
     */
    public Cursor<Object&

网站公告

今日签到

点亮在社区的每一天
去签到