云计算百科
云计算领域专业知识百科平台

SpringDataRedis快速入门

一、前言:为什么用 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 提供两个核心模板类:

模板类Key/Value 类型适用场景
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


九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

赞(0)
未经允许不得转载:网硕互联帮助中心 » SpringDataRedis快速入门
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!