一、前言:为什么用 Spring Data Redis?
你是否还在手动管理 Jedis 连接池? 是否为每个 Redis 操作写重复的 try-finally 代码? 是否希望像操作数据库一样,用声明式方式操作 Redis?
Spring Data Redis 正是为解决这些问题而生!
作为 Spring 官方提供的 Redis 集成模块,它: ✅ 自动管理连接(默认使用高性能 Lettuce 客户端) ✅ 提供 RedisTemplate 和 StringRedisTemplate 简化操作 ✅ 支持序列化定制、事务、管道等高级特性 ✅ 无缝集成 Spring Cache,一行注解实现缓存
本文将带你从零搭建项目,掌握核心 API,并写出优雅的 Redis 代码!
二、环境准备
1. 创建 Spring Boot 项目(2.7+ 或 3.x)
通过 start.spring.io 添加依赖:
- Spring Web
- Spring Data Redis (Access+Driver)
或手动添加 Maven 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!– 若使用 Spring Boot 3.x,无需额外引入 Lettuce –>
📌 注意:Spring Boot 2.x 默认使用 Lettuce(非阻塞、线程安全),不再推荐 Jedis。
2. 启动本地 Redis
# 使用 Docker 快速启动
docker run -d –name redis -p 6379:6379 redis:7.0
三、基础配置:application.yml
spring:
redis:
host: localhost
port: 6379
password: "" # 无密码留空
database: 0
timeout: 2000ms # 连接超时
lettuce:
pool:
max-active: 20 # 最大连接数
max-idle: 10 # 最大空闲连接
min-idle: 2 # 最小空闲连接
max-wait: 2000ms # 获取连接最大等待时间
✅ Spring Boot 会自动配置 RedisConnectionFactory 和 RedisTemplate,无需手动创建连接池!
四、核心操作:RedisTemplate vs StringRedisTemplate
Spring Data Redis 提供两个核心模板类:
| RedisTemplate<K, V> | 泛型(Object) | 存储 Java 对象(需序列化) |
| StringRedisTemplate | String / String | 纯字符串操作(如验证码、计数器) |
1. 使用 StringRedisTemplate(推荐初学者)
@RestController
public class RedisController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("/set")
public String set(@RequestParam String key, @RequestParam String value) {
stringRedisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES);
return "OK";
}
@GetMapping("/get")
public String get(@RequestParam String key) {
return stringRedisTemplate.opsForValue().get(key);
}
// Hash 操作
@PostMapping("/user")
public void saveUser(@RequestParam String userId,
@RequestParam String name,
@RequestParam Integer age) {
stringRedisTemplate.opsForHash().put("user:" + userId, "name", name);
stringRedisTemplate.opsForHash().put("user:" + userId, "age", age.toString());
}
// List 操作
@PostMapping("/task")
public void addTask(@RequestParam String task) {
stringRedisTemplate.opsForList().leftPush("tasks", task);
}
}
✅ 优点:API 清晰,opsForXxx() 对应 Redis 数据类型
2. 使用 RedisTemplate 存储 Java 对象
步骤 1:定义实体类
public class User implements Serializable {
private String id;
private String name;
private int age;
// getter/setter…
}
步骤 2:配置序列化方式(避免乱码)
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 Jackson 序列化对象(可读性强)
Jackson2JsonRedisSerializer<Object> serializer =
new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper);
// 设置 key 和 value 的序列化方式
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
步骤 3:操作对象
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void saveUser(User user) {
redisTemplate.opsForValue().set("user:" + user.getId(), user, 1, TimeUnit.HOURS);
}
public User getUser(String id) {
return (User) redisTemplate.opsForValue().get("user:" + id);
}
💡 提示:若不配置序列化,默认使用 JDK 序列化,会导致 Redis 中出现不可读的二进制数据。
五、常用操作速查表
| String | opsForValue().set("k", "v") |
| Hash | opsForHash().put("user:1", "name", "张三") |
| List | opsForList().rightPush("queue", "item") |
| Set | opsForSet().add("tags", "java", "redis") |
| ZSet | opsForZSet().add("rank", "playerA", 95.5) |
| 过期时间 | expire("key", 60, TimeUnit.SECONDS) |
| 批量操作 | opsForValue().multiSet(map) |
六、进阶:结合 Spring Cache 实现声明式缓存
只需三步,方法结果自动缓存!
1. 启用缓存
@SpringBootApplication
@EnableCaching // ← 关键注解
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2. 在 Service 方法上加注解
@Service
public class UserService {
@Cacheable(value = "users", key = "#id")
public User getUserById(String id) {
System.out.println("查询数据库…"); // 仅首次打印
return userMapper.selectById(id);
}
@CacheEvict(value = "users", key = "#id")
public void updateUser(User user) {
userMapper.update(user);
}
}
✅ 效果:
- 第一次调用 getUserById("1001") → 查询 DB 并缓存
- 后续调用 → 直接返回缓存,不执行方法体
七、常见问题与避坑指南
❌ 坑 1:Redis 中出现 \\xac\\xed\\x00\\x05 乱码
原因:使用了默认的 JDK 序列化 解决:配置 StringRedisSerializer 或 Jackson2JsonRedisSerializer
❌ 坑 2:缓存穿透(大量查不存在的 key)
方案:对 null 结果也缓存(短 TTL),或使用布隆过滤器
❌ 坑 3:缓存雪崩(大量 key 同时过期)
方案:设置随机过期时间,如 600 + random(60)
八、Jedis vs Lettuce vs Spring Data Redis
| 原生 Jedis | 学习 Redis 协议、极简项目 |
| JedisPool | 需要精细控制连接池的中小项目 |
| Spring Data Redis (Lettuce) | ✅ 主流选择:Spring Boot 项目、高并发、响应式支持 |
📌 建议:新项目直接使用 Spring Data Redis + Lettuce
九、结语
感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!
网硕互联帮助中心



评论前必须登录!
注册