SpringBoot Redis 整合
# Redis整合
SpringData是Spring中数据操作的模块 , 该模块集成了很多数据库操作 , 其中也包括 Reids
官方 : https://spring.io/projects/spring-data-redis/ (opens new window)
优点 :
- 整合了 Lettuce 和 jedis
- 提供 ReidsTemplate统一API操作
- 支持 同步/异步/响应式编程
- 线程安全
- 支持 哨兵模式/集群/管道 模式
- 支持 发布订阅模型
- 支持基于 JDK/JSON/字符串/Spring 对象的 序列化/反序列化
# 提供操作方法
SpringDataRedis提供RedisTemplate工具类 , 里面封装了各种Reids操作功能 , 分别介绍 :
Key相关
返回 | API | 说明 |
---|---|---|
ValueOperations | redisTemplate.opsForValue() | 操作String类型 |
HashOperations | redisTemplate.opsForHash() | 操作Hash类型 |
ListOperations | redisTemplate.opsForList() | 操作List类型 |
SetOperations | redisTemplate.opsForSet() | 操作Set类型 |
ZSetOperations | redisTemplate.opsForZSet() | 操作SortedSet类型 |
Boolean | expire(key, timeout) | 设置key的过期时间 |
Boolean | persist(key) | 移除key的过期时间, 使key永久存在 |
void | rename(oldKey, newKey) | 修改key的名称 |
Boolean | delete(key) | 删除key |
String相关
操作工具 :
- opsForValue() : 返回ValueOperations接口 , 可以执行get、set、increment等操
- boundValueOps() : 同opsForValue , 但可以设置过期时间
返回 | API | 说明 |
---|---|---|
String | get(key) | 获取String值 |
Boolean | set(key, value) | 设置String值 |
Long | increment(key) | String值增加1 |
Long | decrement(key) | String值减少1 |
Hash相关
- opsForHash() : 返回HashOperations接口 , 可以执行hget、hset、hincrBy等操作
- boundHashOps() : 同opsForHash , 但可以设置过期时间
返回 | API | 说明 |
---|---|---|
Map<HK, HV> | entries(key) | 获取Hash所有的值 |
HV | get(key, hk) | 获取Hash中hk的value |
void | put(key, hk, hv) | 设置Hash中的hk为hv |
Long | increment(key, hk) | Hash中hk的值增加1 |
Long | decrement(key, hk) | Hash中hk的值减少1 |
List相关
- opsForList() : 返回ListOperations接口 , 可以执行lpush、rpush、lrange等操作
- boundListOps() :同opsForList , 但可以设置过期时间
返回 | API | 说明 |
---|---|---|
List<V> | opsForList().range(key, start, end) | 获取List指定范围的值 |
Long | opsForList().size(key) | 获取List长度 |
void | opsForList().leftPush(key, v) | 在List左侧添加v |
void | opsForList().rightPush(key, v) | 在List右侧添加v |
void | opsForList().leftPop(key) | 在List左侧弹出一个值 |
void | opsForList().rightPop(key) | 在List右侧弹出一个值 |
void | opsForList().remove(key, v1, v2) | 从List中移除v1到v2之间的值 |
void | opsForList().trim(key, start, end) | 裁切List,只保留start到end之间的值 |
Set相关
- opsForSet() : 返回SetOperations接口 , 可以执行sadd、smembers、sismember等操作
- boundSetOps() : 同opsForSet , 但可以设置过期时间
返回 | API | 说明 |
---|---|---|
Set<V> | opsForSet().members(key) | 获取Set中所有的值 |
Boolean | opsForSet().isMember(key, v) | 判断v是否在Set中 |
Long | opsForSet().size(key) | 获取Set大小 |
void | opsForSet().add(key, v1, v2, v3) | 向Set中添加v1,v2,v3 |
void | opsForSet().remove(key, v1, v2) | 从Set中移除v1,v2 |
ZSet相关
- opsForZSet() : 返回ZSetOperations接口 , 可以执行zadd、zrange、zrem等操作
- boundZSetOps() : 同opsForZSet , 但可以设置过期时间
返回 | API | 说明 |
---|---|---|
Set<V> | opsForZSet().range(key, start, end) | 获取ZSet指定范围的值 |
Set<V> | opsForZSet().rangeByScore(key, min, max) | 获取ZSet分数范围的值 |
Long | opsForZSet().zCard(key) | 获取ZSet大小 |
Double | opsForZSet().score(key, v) | 获取v在ZSet中的分数 |
void | opsForZSet().add(key, v, score) | 向ZSet中添加v并设置分数score |
void | opsForZSet().remove(key, v) | 从ZSet中移除v |
# 快速应用
大致步骤 :
- 引入依赖
- 配置参数
- 配置类配置
- CRUD测试
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置Reids基本参数
# redis 配置 (端口/地址/密码/连接池配置)
spring:
data:
redis:
port: 6379
host: localhost
password: 123123
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 100ms
提示
我使用的是SprinBoot3.0.4版本 , 旧版本没有data节点
配置类 配置
@Configuration
public class RidesConfig {
/**
* 自定义配置 RedisTemplate
* @param connectionFactory 连接工厂
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置 key序列化器 RedisSerializer
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// 设置 连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
测试 CRUD
测试类 展开
@Resource
private RedisTemplate redisTemplate;
@Test
public void add() {
ValueOperations ops = redisTemplate.opsForValue();
ops.set("String","Sans");
String[] stat = {"zs1","zs2"};
ops.set("List",Arrays.toString(stat));
ops.set("Int",666);
ops.set("double",6.6);
User user = new User();
user.setId(9);
user.setUsername("Sans111");
ops.set("user",user);
}
@Test
public void show() {
ValueOperations ops = redisTemplate.opsForValue();
System.out.println("String =>" + ops.get("String"));
System.out.println("List =>" + ops.get("List"));
System.out.println("Int =>" + ops.get("Int"));
System.out.println("double =>" + ops.get("double"));
System.out.println("user =>" + ops.get("user"));
}
@Test
public void del() {
redisTemplate.delete("String");
redisTemplate.delete("List");
redisTemplate.delete("Int");
redisTemplate.delete("double");
redisTemplate.delete("user");
}
提示
SpringBoot3.02版本以下 , 采用 @Resource
注解 自动注入 , 需要添加name参数进行指定名称Bean的方法名称 , 例如 :
@Resource(name="redisTemplate")
private RedisTemplate redisTemplate;
# 自定义序列化器
默认采用的jdk序列化对key和value造成乱码 , 无难以阅读 , 而且乱码在外部获取也不方便 , 因此 需要执行配置序列化
文章参考 :
- https://developer.aliyun.com/article/907866 (opens new window)
- https://developer.aliyun.com/article/907868 (opens new window)
- https://developer.aliyun.com/article/907869 (opens new window)
RedisConfig配置类
@Configuration
public class RidesConfig {
/**
* 自定义配置 RedisTemplate
* @param connectionFactory 连接工厂
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置 key序列化器 RedisSerializer
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// 设置 连接工厂
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
# Redisson应用
Redisson是 Redis基础上实现分布式工具框架 , 分布式场景各种各样的工具均可实现
官方 : https://redisson.org (opens new window)
GitHub : https://github.com/redisson/redisson (opens new window)
个人笔记 : Redis篇章中的Redisson
依赖
<!--redisson-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.17.6</version>
</dependency>
配置类 Redisson客户端
@Configuration
public class ReidssonConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://ip地址:6379")
.setPassword("123123");
// 创建 RedissonClient
return Redisson.create(config);
}
}
简单实现分布式锁
@Resource
private RedissionClient redissonClient;
@Test
void testRedisson() {
//获取锁(可重入),指定锁的名称
RLock lock = redissonClient.getLock("anyLock");
try{
//尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位
boolean isLock = lock.tryLock(1,10,TimeUnit.SECONDS);
if (!isLock) throw new BusinessException("获取锁失败!");
System.out.println("执行业务");
}catch (InterruptedException e) {
throw new RuntimeException(e);
}finally{
// 释放锁
lock.unlock();
}
}