RedisTemplate在Spring Boot中的五种数据结构全面详解
📋目录
🔧 环境配置
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: localhostport: 6379database: 0timeout: 3000mslettuce:pool:max-active: 200max-idle: 20min-idle: 5max-wait: -1ms
3. Redis配置类
@Configuration
public class RedisConfig {@Beanpublic 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 {@Autowiredprivate 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 {@Autowiredprivate 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 {@Autowiredprivate 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> scan(String key, ScanOptions options) {return redisTemplate.ops