当前位置: 首页 > news >正文

RedisTemplate 实战:Spring 项目中 Redis 操作的全维度指南

在 Spring 生态中,RedisTemplate 是操作 Redis 的核心工具类,它封装了 Redis 的底层命令,让开发者能以面向对象的方式轻松操作 Redis 各种数据结构。本文将从配置、基础使用到高级场景,全面讲解如何在 Spring 项目中利用 RedisTemplate 玩转 Redis。

一、RedisTemplate 配置与初始化

要在 Spring 项目中使用 RedisTemplate,首先需要完成依赖引入和配置类编写。

1. 引入依赖(Maven)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 可选:使用 Lettuce 连接池(Spring Boot 默认推荐) -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

2. 编写 Redis 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// Key 序列化器:使用 String 序列化template.setKeySerializer(new StringRedisSerializer());// Value 序列化器:使用 JSON 序列化,支持对象存储template.setValueSerializer(new GenericJackson2JsonRedisSerializer());// Hash Key 序列化器template.setHashKeySerializer(new StringRedisSerializer());// Hash Value 序列化器template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());template.afterPropertiesSet();return template;}
}

配置说明

  • 序列化器选择:StringRedisSerializer 保证 Key 是可读的字符串;GenericJackson2JsonRedisSerializer 支持对象的 JSON 序列化 / 反序列化,可直接存储实体类。
  • 连接工厂:由 Spring Boot 自动配置,默认使用 Lettuce 连接池(高性能、线程安全)。

二、RedisTemplate 核心操作:五大数据结构实战

1. 字符串(String)操作

字符串是 Redis 最基础的数据结构,RedisTemplate 中通过 opsForValue() 进行操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
public class RedisStringService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 设置字符串public void setString(String key, String value) {redisTemplate.opsForValue().set(key, value);}// 设置带过期时间的字符串(单位:秒)public void setStringWithExpire(String key, String value, long seconds) {redisTemplate.opsForValue().set(key, value, seconds);}// 获取字符串public String getString(String key) {return (String) redisTemplate.opsForValue().get(key);}// 数字自增public Long increment(String key, long delta) {return redisTemplate.opsForValue().increment(key, delta);}// 数字自减public Long decrement(String key, long delta) {return redisTemplate.opsForValue().decrement(key, delta);}
}

场景示例:用户登录次数统计、文章阅读量计数。

2. 哈希(Hash)操作

哈希适合存储对象(如用户信息、商品详情),通过 opsForHash() 操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Map;@Component
public class RedisHashService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 设置哈希字段public void putHash(String key, String hashKey, Object value) {redisTemplate.opsForHash().put(key, hashKey, value);}// 批量设置哈希字段public void putAllHash(String key, Map<String, Object> map) {redisTemplate.opsForHash().putAll(key, map);}// 获取哈希字段public Object getHash(String key, String hashKey) {return redisTemplate.opsForHash().get(key, hashKey);}// 获取所有哈希字段和值public Map<Object, Object> getAllHash(String key) {return redisTemplate.opsForHash().entries(key);}// 删除哈希字段public Long deleteHash(String key, Object... hashKeys) {return redisTemplate.opsForHash().delete(key, hashKeys);}
}

场景示例:存储用户信息(user:1001 作为 Key,name/age/gender 作为 HashKey)。

3. 列表(List)操作

列表是有序可重复的集合,支持两端插入 / 弹出,通过 opsForList() 操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.List;@Component
public class RedisListService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 从列表左侧添加元素public Long leftPush(String key, Object value) {return redisTemplate.opsForList().leftPush(key, value);}// 从列表右侧添加元素public Long rightPush(String key, Object value) {return redisTemplate.opsForList().rightPush(key, value);}// 从列表左侧弹出元素public Object leftPop(String key) {return redisTemplate.opsForList().leftPop(key);}// 从列表右侧弹出元素public Object rightPop(String key) {return redisTemplate.opsForList().rightPop(key);}// 获取列表指定范围元素public List<Object> range(String key, long start, long end) {return redisTemplate.opsForList().range(key, start, end);}
}

场景示例:消息队列(leftPush 生产,rightPop 消费)、用户操作时间轴。

4. 集合(Set)操作

集合是无序不可重复的集合,支持交集、并集运算,通过 opsForSet() 操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Set;@Component
public class RedisSetService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 向集合添加元素public Long add(String key, Object... values) {return redisTemplate.opsForSet().add(key, values);}// 获取集合所有元素public Set<Object> members(String key) {return redisTemplate.opsForSet().members(key);}// 判断元素是否在集合中public Boolean isMember(String key, Object value) {return redisTemplate.opsForSet().isMember(key, value);}// 计算两个集合的交集public Set<Object> intersect(String key1, String key2) {return redisTemplate.opsForSet().intersect(key1, key2);}
}

场景示例:用户标签(user:1001:tags 存储用户兴趣标签)、好友共同关注。

5. 有序集合(ZSet)操作

有序集合按分数排序,适合排行榜场景,通过 opsForZSet() 操作。

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Set;@Component
public class RedisZSetService {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 向有序集合添加元素(带分数)public Boolean add(String key, Object value, double score) {return redisTemplate.opsForZSet().add(key, value, score);}// 按分数升序获取元素public Set<Object> range(String key, long start, long end) {return redisTemplate.opsForZSet().range(key, start, end);}// 按分数降序获取元素(带分数)public Set<org.springframework.data.redis.core.ZSetOperations.TypedTuple<Object>> rangeWithScores(String key, long start, long end) {return redisTemplate.opsForZSet().rangeWithScores(key, start, end);}// 元素分数自增public Double incrementScore(String key, Object value, double delta) {return redisTemplate.opsForZSet().incrementScore(key, value, delta);}// 获取元素排名(升序)public Long rank(String key, Object value) {return redisTemplate.opsForZSet().rank(key, value);}
}

场景示例:文章阅读量排行榜(rank:article 作为 Key,文章 ID 作为 Value,阅读量作为 Score)。

三、RedisTemplate 高级特性

1. 事务支持

RedisTemplate 支持 Redis 事务,通过 multi()/exec() 实现。

public void transactionDemo() {redisTemplate.multi(); // 开启事务redisTemplate.opsForValue().set("key1", "value1");redisTemplate.opsForValue().set("key2", "value2");List<Object> results = redisTemplate.exec(); // 执行事务// results 包含每个命令的执行结果
}

注意:Redis 事务是 “弱事务”,仅保证命令的原子性(要么全执行,要么全不执行),但不支持回滚。

2. 管道(Pipeline)

管道用于批量执行命令,减少网络往返次数,提升性能。

public void pipelineDemo() {redisTemplate.executePipelined((RedisCallback<Object>) connection -> {for (int i = 0; i < 1000; i++) {connection.set(redisTemplate.getKeySerializer().serialize("key:" + i),redisTemplate.getValueSerializer().serialize("value:" + i));}return null;});
}

3. 分布式锁

基于 RedisTemplate 实现简单分布式锁:

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;
import java.util.concurrent.TimeUnit;@Component
public class RedisDistributedLock {@Resourceprivate RedisTemplate<String, Object> redisTemplate;private static final String LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;static {UNLOCK_SCRIPT = new DefaultRedisScript<>();UNLOCK_SCRIPT.setScriptText(LOCK_SCRIPT);UNLOCK_SCRIPT.setResultType(Long.class);}// 加锁public boolean lock(String key, long expireTime, TimeUnit timeUnit) {String uuid = UUID.randomUUID().toString();Boolean result = redisTemplate.opsForValue().setIfAbsent(key, uuid, expireTime, timeUnit);return result != null && result;}// 解锁public boolean unlock(String key) {String uuid = (String) redisTemplate.opsForValue().get(key);if (uuid == null) {return false;}Long result = redisTemplate.execute(UNLOCK_SCRIPT, Collections.singletonList(key), uuid);return result != null && result > 0;}
}

四、最佳实践与避坑指南

1. 序列化器选择

  • Key 序列化:统一使用 StringRedisSerializer,保证 Key 是可读的字符串。
  • Value 序列化
    • 存储简单类型(String、Integer):可用 StringRedisSerializer
    • 存储实体类:推荐 GenericJackson2JsonRedisSerializer 或 Jackson2JsonRedisSerializer,支持对象的序列化 / 反序列化。

2. 连接池配置(Lettuce)

在 application.yml 中配置连接池参数,避免连接泄漏或性能瓶颈:

spring:redis:lettuce:pool:max-active: 8   # 最大连接数max-idle: 8    # 最大空闲连接数min-idle: 0    # 最小空闲连接数max-wait: -1ms # 连接获取超时时间(-1 表示不超时)

3. 避免常见问题

  • BigKey 问题:避免存储过大的字符串或哈希,否则会阻塞 Redis 线程。可拆分大对象或使用 Redis 分片。
  • 热点 Key 问题:热点 Key 可通过本地缓存 + Redis 多级缓存缓解压力。
  • 事务与 Pipeline 混用:事务和管道不要同时使用,否则可能导致命令执行顺序异常。

总结

RedisTemplate 是 Spring 整合 Redis 的 “利器”,它封装了 Redis 所有核心数据结构的操作,同时提供事务、管道、分布式锁等高级功能。掌握它的使用,能让你在 Spring 项目中高效地利用 Redis 实现缓存、计数、队列、排行榜等场景。

在实际开发中,建议将 RedisTemplate 封装为工具类(如本文开头的 RedisService),统一管理 Redis 操作,提升代码的可维护性和可读性。

http://www.dtcms.com/a/594128.html

相关文章:

  • Doris Docker 完整部署指南
  • C语言算法:排序算法入门
  • seo简单优化sem和seo都包括什么
  • 舞蹈培训机构网站建设上门做网站公司哪家好
  • Unity Tilemap小方块(瓦片)颜色的更改
  • 中国建设银行网站首页u盾登入网站建设小
  • Java 基本语法:从小白到大师的编程之路!
  • SPARQL 1.1 BNF浅析
  • Java基础——集合进阶用到的数据结构知识点4
  • 四、神经网络
  • 数据结构之红黑树
  • 上海 网站备案拍照推广公众号平台的公司
  • 自学网站有哪些深圳建企业网站
  • 课程网站开发合同英文网站有哪些
  • Android内核进阶之pcm硬件参数最小约束值snd_pcm_hw_param_first:用法实例(八十七)
  • Node-RED:输入节点全家桶:数据从哪里来?
  • AI 大模型训练 / 推理的 CPU/GPU 选型指南整理 (仅供参考)
  • 桂林网站优化公司wordpress换空间搬家
  • 青岛网站建设制作公司WordPress 网站成本
  • 现代数据库系统数据结构 B+Tree
  • 佛山专业网站营销企业官方网站管理制度
  • 竞价单页网站制作教程阿里巴巴国际站怎么找客户
  • Attention复杂度解析与改进方向
  • 化工网站建设推广南通做网站的
  • 寻找网站建设员网站开发要跑道吗
  • 集成式智能体开发流程提示词
  • 保定免费建站服务医院男性男科
  • 农业数据集目标检测分割分类数据集汇总介绍
  • 做网站公司在深圳培训学校机构有哪些
  • 织梦 两个网站网站该怎么找到