Springboot使用Redis
以下是 Spring Boot 操作 Redis 的完整方法笔记,涵盖基础操作、高级特性、事务、管道、分布式锁等场景,并提供代码示例和最佳实践。
一、环境配置
1. 添加依赖
1 2 3 4 5 6 7 8 9
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>
|
2. 配置文件
1 2 3 4 5 6 7 8 9 10 11 12
| spring: redis: host: 127.0.0.1 port: 6379 password: yourpassword lettuce: pool: max-active: 8 max-wait: -1ms max-idle: 8 min-idle: 0
|
二、基础操作
1. 注入 RedisTemplate
或 StringRedisTemplate
1 2 3 4 5
| @Autowired private RedisTemplate<String, Object> redisTemplate;
@Autowired private StringRedisTemplate stringRedisTemplate;
|
2. 常用数据操作
操作类型 | 方法示例 | 说明 |
---|
String | redisTemplate.opsForValue().set("key", "value") | 设置值 |
| String value = stringRedisTemplate.opsForValue().get("key") | 获取值 |
Hash | redisTemplate.opsForHash().put("user", "name", "Alice") | 设置Hash字段 |
| Map<Object, Object> user = redisTemplate.opsForHash().entries("user") | 获取整个Hash |
List | redisTemplate.opsForList().rightPush("list", "item1") | 右插入列表 |
| List<Object> items = redisTemplate.opsForList().range("list", 0, -1) | 获取列表范围 |
Set | redisTemplate.opsForSet().add("set", "a", "b", "c") | 添加集合元素 |
| Set<Object> set = redisTemplate.opsForSet().members("set") | 获取所有集合元素 |
ZSet | redisTemplate.opsForZSet().add("zset", "member", 90.0) | 添加有序集合元素(带分数) |
| Set<Object> top3 = redisTemplate.opsForZSet().range("zset", 0, 2) | 获取排名前3的元素 |
三、高级特性
1. 序列化配置(解决Java对象存储)
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer()); template.setKeySerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); return template; } }
|
2. 发布/订阅
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| stringRedisTemplate.convertAndSend("channel", "Hello Redis!");
@Component public class RedisMessageListener implements MessageListener { @Override public void onMessage(Message message, byte[] pattern) { System.out.println("收到消息: " + new String(message.getBody())); } }
@Bean public RedisMessageListenerContainer container(RedisConnectionFactory factory, RedisMessageListener listener) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(factory); container.addMessageListener(listener, new ChannelTopic("channel")); return container; }
|
四、事务与管道
1. 事务操作
1 2 3 4 5 6 7 8 9 10 11 12 13
| redisTemplate.setEnableTransactionSupport(true);
List<Object> results = redisTemplate.execute(new SessionCallback<>() { @Override public List<Object> execute(RedisOperations operations) { operations.multi(); operations.opsForValue().set("k1", "v1"); operations.opsForValue().set("k2", "v2"); return operations.exec(); } });
|
2. 管道批处理
1 2 3 4 5 6 7 8 9
| List<Object> results = redisTemplate.executePipelined(new SessionCallback<>() { @Override public Object execute(RedisOperations operations) { for (int i = 0; i < 1000; i++) { operations.opsForValue().set("pipe_" + i, "value_" + i); } return null; } });
|
五、分布式锁
1. 基于 SETNX
的实现
1 2 3 4 5 6 7 8 9 10 11 12
| public boolean tryLock(String key, String value, long expireTime) { Boolean result = stringRedisTemplate.opsForValue() .setIfAbsent(key, value, expireTime, TimeUnit.SECONDS); return Boolean.TRUE.equals(result); }
public void unlock(String key, String value) { if (value.equals(stringRedisTemplate.opsForValue().get(key))) { stringRedisTemplate.delete(key); } }
|
2. 使用 Redisson(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.17.0</version> </dependency>
@Autowired private RedissonClient redisson;
public void doWithLock() { RLock lock = redisson.getLock("myLock"); try { lock.lock(10, TimeUnit.SECONDS); } finally { lock.unlock(); } }
|
六、缓存注解(Spring Cache)
1. 启用缓存
1 2 3
| @SpringBootApplication @EnableCaching public class Application { ... }
|
2. 常用注解
注解 | 作用 |
---|
@Cacheable | 方法结果缓存(如@Cacheable(value="users", key="#userId") ) |
@CachePut | 更新缓存(如@CachePut(value="users", key="#user.id") ) |
@CacheEvict | 删除缓存(如@CacheEvict(value="users", key="#userId") ) |
@Caching | 组合多个缓存操作 |
3. 自定义Redis缓存配置
1 2 3 4 5 6 7 8 9 10
| @Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair .fromSerializer(new GenericJackson2JsonRedisSerializer())) .entryTtl(Duration.ofMinutes(30)); return RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); }
|
七、性能优化与陷阱
- 连接池配置:根据QPS调整
max-active
(建议≥50并发) - 序列化选择:
- 字符串操作:
StringRedisSerializer
- 对象存储:
GenericJackson2JsonRedisSerializer
- 避免大Key:单个Value不超过1MB(推荐≤10KB)
- 管道 vs 事务:
八、完整工具类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Component public class RedisUtils { @Autowired private RedisTemplate<String, Object> redisTemplate;
public void set(String key, Object value, long timeout, TimeUnit unit) { redisTemplate.opsForValue().set(key, value, timeout, unit); }
public <T> T get(String key, Class<T> clazz) { Object value = redisTemplate.opsForValue().get(key); return clazz.cast(value); }
public Boolean delete(String key) { return redisTemplate.delete(key); }
public Long deleteByPattern(String pattern) { Set<String> keys = redisTemplate.keys(pattern + "*"); return keys != null ? redisTemplate.delete(keys) : 0L; } }
|
通过以上方法,你可以覆盖Spring Boot操作Redis的绝大多数场景。根据业务需求选择合适的操作方式,并注意性能与安全性的平衡。