SpringDataRedis快速入门

SpringDataRedis快速入门 一、前言为什么用 Spring Data Redis在 Spring Boot 项目中直接使用 Jedis 或 Lettuce 操作 Redis 虽然灵活但存在以下问题❌ 需手动管理连接、异常处理❌ 序列化/反序列化逻辑重复❌ 无法享受 Spring 的依赖注入、AOP、事务等特性而Spring Data Redis作为 Spring 官方提供的 Redis 集成模块提供了✅自动配置开箱即用✅统一 APIRedisTemplate/StringRedisTemplate✅对象序列化支持✅Repository 模式类似 JPA操作 Hash✅与 Spring 生态无缝集成本文将带你从零搭建 Spring Data Redis 环境并实现常用操作。二、环境准备2.1 前提条件JDK 8Spring Boot 2.7默认使用 LettuceRedis 服务本地或远程# 启动本地 RedisDocker docker run -d --name redis -p 6379:6379 redis:7.22.2 Maven 依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency !-- 若需连接池Lettuce 默认不依赖连接池但推荐添加 -- dependency groupIdorg.apache.commons/groupId artifactIdcommons-pool2/artifactId /dependency注意Spring Boot 2.x 默认客户端是Lettuce非阻塞、线程安全而非 Jedis。三、基础配置application.ymlspring: redis: host: localhost port: 6379 password: # 无密码留空 database: 0 timeout: 2000ms # 连接超时 lettuce: pool: max-active: 8 # 最大连接数 max-idle: 8 # 最大空闲连接 min-idle: 0 # 最小空闲连接 max-wait: -1ms # 获取连接最大等待时间-1 表示无限✅ 启动时Spring Boot 会自动创建RedisConnectionFactory、RedisTemplate等 Bean。四、核心组件RedisTemplate vs StringRedisTemplate组件Key/Value 类型适用场景RedisTemplateK, V泛型Object存储 Java 对象需配置序列化StringRedisTemplateString / String存储字符串、JSON、简单 KV4.1 使用 StringRedisTemplate推荐用于简单场景Service public class CacheService { Autowired private StringRedisTemplate stringRedisTemplate; public void set(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } public void setEx(String key, String value, long timeout, TimeUnit unit) { stringRedisTemplate.opsForValue().set(key, value, timeout, unit); } public String get(String key) { return stringRedisTemplate.opsForValue().get(key); } // List 操作 public void lpush(String key, String... values) { stringRedisTemplate.opsForList().leftPushAll(key, values); } // Set 操作 public void sadd(String key, String... values) { stringRedisTemplate.opsForSet().add(key, values); } // ZSet 操作 public void zadd(String key, double score, String member) { stringRedisTemplate.opsForZSet().add(key, member, score); } }4.2 使用 RedisTemplate存储 Java 对象步骤 1配置序列化方式避免乱码Configuration EnableRedisRepositories // 启用 Redis Repository public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(factory); // 使用 Jackson 序列化 Jackson2JsonRedisSerializerObject serializer new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, 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; } }步骤 2操作对象Service public class UserService { Autowired private RedisTemplateString, Object redisTemplate; public void saveUser(User user) { redisTemplate.opsForValue().set(user: user.getId(), user, 1, TimeUnit.HOURS); } public User getUser(Long id) { return (User) redisTemplate.opsForValue().get(user: id); } }✅优势自动完成对象 ↔ JSON 转换无需手动JSON.toJSONString()五、高级特性Redis Repository操作 HashSpring Data Redis 支持类似 JPA 的Repository 模式专用于操作Hash 类型。5.1 定义实体类RedisHash(user) // Hash key 前缀 public class User { Id private Long id; private String name; private Integer age; // 构造函数、getter/setter 略 }5.2 定义 Repository 接口public interface UserRepository extends CrudRepositoryUser, Long { // 自动继承 save(), findById(), delete() 等方法 }5.3 使用 RepositoryService public class UserService { Autowired private UserRepository userRepository; public void save(User user) { userRepository.save(user); // 实际执行HSET user:id name Alice age 25 } public OptionalUser findById(Long id) { return userRepository.findById(id); } }底层原理Hash key user:id字段 对象属性自动序列化为字符串⚠️注意Repository 仅适用于Hash且实体必须有Id六、常见操作封装示例6.1 分布式锁基于 RedisTemplatepublic boolean tryLock(String lockKey, String requestId, int expireSeconds) { Boolean result stringRedisTemplate.execute( (RedisCallbackBoolean) connection - connection.set(lockKey.getBytes(), requestId.getBytes(), Expiration.seconds(expireSeconds), RedisStringCommands.SetOption.SET_IF_ABSENT) ); return Boolean.TRUE.equals(result); } public void unlock(String lockKey, String requestId) { // 安全解锁需 Lua 脚本略 stringRedisTemplate.delete(lockKey); }6.2 缓存工具类Component public class RedisCache { Autowired private StringRedisTemplate redisTemplate; public T void set(String key, T value, long timeout, TimeUnit unit) { redisTemplate.opsForValue().set(key, JSON.toJSONString(value), timeout, unit); } public T T get(String key, ClassT clazz) { String json redisTemplate.opsForValue().get(key); return json null ? null : JSON.parseObject(json, clazz); } }七、序列化方案对比方案优点缺点适用场景JDK 序列化默认无需配置体积大、跨语言不兼容内部系统StringJSON可读、通用需手动转换Web API、前后端交互Jackson2Json自动对象映射需配置存储 POJOProtobuf体积小、高效需定义 schema高性能微服务✅推荐Web 项目优先使用Jackson2JsonRedisSerializer八、最佳实践与避坑指南✅ 最佳实践优先使用StringRedisTemplate处理字符串、JSON对象缓存务必配置序列化避免 乱码key 命名规范如user:{id}:profile设置 TTL防止内存泄漏监控 Redis 内存与连接数❌ 常见错误未配置序列化→ Redis 中看到aced0005...JDK 序列化结果直接存储大对象→ 网络传输慢、内存爆炸忘记加EnableRedisRepositories→ Repository 无法注入九、结语感谢您的阅读如果你有任何疑问或想要分享的经验请在评论区留言交流