SpringBoot整合Redis实现基本操作
Redis应用场景:
- 缓存
- 任务队列
- 网站访问统计
- 应用排行榜
- 数据过期处理
- 分布式集群架构中的 session 分离
整合方式:使用注解和不适用注解
注意:实体类必须实现序列化接口:
implements Serializable
Redis
五种数据结构
结构类型 结构存储的值 结构的读写能力 String 可以是字符串、整数或者浮点数 对整个字符串或者字符串的其中一部分执行操作;对象和浮点数执行自增(increment)或者自减(decrement) List 一个链表,链表上的每个节点都包含了一个字符串 从链表的两端推入或者弹出元素;根据偏移量对链表进行修剪(trim);读取单个或者多个元素;根据值来查找或者移除元素 Set 包含字符串的无序收集器(unorderedcollection),并且被包含的每个字符串都是独一无二的、各不相同 添加、获取、移除单个元素;检查一个元素是否存在于某个集合中;计算交集、并集、差集;从集合里卖弄随机获取元素 Hash 包含键值对的无序散列表 添加、获取、移除单个键值对;获取所有键值对 Zset 字符串成员(member)与浮点数分值(score)之间的有序映射,元素的排列顺序由分值的大小决定 添加、获取、删除单个元素;根据分值范围(range)或者成员来获取元素
前导操作
Redis安装启动,先引入依赖(注意版本):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
在项目的application.yml中加入redis相关配置:
spring redis: host:172.17.2.94 port: 6379 password: root@123456 database: 0
注解方式(SpringCache)
须在启动类上添加注解允许缓存:
@EnableCaching
导入依赖坐标:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
配置
application.yml
:spring: cache: redis: time-to-live: 1800000#设置缓存有效期
@Cacheable
:- 作用:用于查询和添加缓存,第一次查询的时候返回该方法返回值,并向 Redis 服务器保存数据,之后调用该方法先从 Redis 中查是否有数据,如果有直接返回 Redis 缓存的数据,而不执行方法里的代码。如果没有则正常执行方法体中的代码。
- 常用属性:
value
或cacheNames
属性做键,key
属性则可以看作为value
的子键, 一个value
可以有多个 key组成
不同值存在 Redis 服务器,并且value
和cacheNames
属性只能定义一个,用于表示主键。condition
和unless
是条件,如condition = "#openid.length > 3", unless = "#result.code != 0"
。 - 使用示例:
- 字符串做key:
@Cacheable(cacheNames = "product", key = "toy")
,cacheNames
和key
都必须填,如果不填key
,默认的key
是当前的方法名,更新缓存时会因为方法名不同而更新失败。 - 对象(若参数为对象)属性做key并添加条件:
@Cacheable(cacheNames = "prodcut", key = "#user.id", condition = "#openid.length > 3", unless = "#result.code != 0")
,此时#user.id
为属性,condition
为条件成立时缓存,unless
为条件不成立时缓存,#result
为返回结果。 - 字符串拼接做key:
@Cacheable(value = "product" , key = "'one-'+#p0",unless = "#result==null")
,拼接时双引号中的字符串需要用单引号引起来,用“+”连接。
- 字符串做key:
@CachePut
:- 作用:更新 Redis 中对应键的值。
- 属性:和
@Cacheable
相同。 - 使用示例:在需要更新缓存的方法上添加注解:
@CachePut(cacheNames = "prodcut", key = "toy")
cacheNames
和key
要跟@Cacheable()
里的一致,才会正确更新;@CachePut()
和@Cacheable()
注解的方法返回值要一致。
@CacheEvict
:- 作用:删除Redis中的对应缓存。
- 属性:和
@Cacheable
相同。 - 使用示例:在需要删除缓存的方法上加注解:
@CacheEvict(cacheNames = "prodcut", key = "toy")
RedisTemplate
和StringRedisTemplate
方式
添加配置类
RedisConfig
:@Configuration public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){ RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>(); //默认的Key序列化器为: JdkSerializationRedisSerializer redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory( connectionFactory) ; return redisTemplate; } }
在需要操作缓存的
Controller
层注入:@Autowired private RedisTemplate redisTemplate; @Autowired private StringRedisTemplate stringRedisTemplate;
操作(以
opsForValue()
为例):- 加入缓存:
redisTemplate.opsForValue().set("product","toy",5, TimeUnit.MINUTES);
,缓存存活时间为5Min; - 获取缓存:
Object codeInSession =redisTemplate.opsForValue().get("product");
,类型可强转; - 删除缓存:
redisTemplate.delete("product");
- 加入缓存:
RedisTemplate 对五种数据结构分别定义了操作:
- 操作字符串:
redisTemplate.opsForValue()
- 操作Hash:
redisTemplate.opsForHash()
- 操作List:
redisTemplate.opsForList()
- 操作Set:
redisTemplate.opsForSet()
- 操作有序Set:
redisTemplate.opsForZSet()
- 操作字符串:
StringRedisTemplate
与RedisTemplate
的区别- 关系不同:StringRedisTemplate继承了RedisTemplate;
- 序列化策略不同:StringRedisTemplate 使用的是 StringRedisSerializer 类;RedisTemplate 使用的是 JdkSerializationRedisSerializer 类,若反序列化,则StringRedisTemplate 得到 String,RedisTemplate 得到 Object,并且StringRedisTemplate 只能对 key=String,value=String 的键值对进行操作,RedisTemplate 可以对任何类型的 key-value 键值对操作。
- 两者数据不互通:RedisTemplate不能取StringRedisTemplate存入的数据,StringRedisTemplate不能取RedisTemplate存入的数据。