简单介绍一下Spring Data Redis的使用,和一点点小坑.
1.在pom.xml中引入maven依赖.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.api简单介绍.
Spring Data Redis为我们提供了一个高度封装的类:RedisTemplate.在需要使用的地方可以直接依赖注入.
@Autowired
private RedisTemplate redisTemplate;
PS:这里有一个坑点.你需要注意你的SpringBoot的版本号,笔者发布该文章的时候,SpringBoot官网默认安装的最新版已是2.7.0,由于在该版本中并没有自动配置SpringDataRedis,所以RedisTemplate的引入,会报异常.如果想要方便测试,可直接使用SpringBoot 2.4.5 版本(有兴趣的可在文章最后查看配置文件预览内容).
3.此时RedisTemplate已经可以进行读写,但它默认会将我们的存取的键与值都进行转义,会对我们的操作带来很大的不方便,因此我们还需要增加一个config配置类.
package com.taotaotao.jireiwaimai.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
// 修改序列化工具,默认的key序列化器为: JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// 生产环境下,value不要序列化
// value通过String序列化的
// 好处:我们可以很方便的查看
// 坏处:我们存的时候,需要JSON化,取的时候,也需要JSON化
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
PS:生产环境一般只配置Key的序列化,不配置Value的序列化,它会以默认的一套规则,将内容序列化成字符串存储.如果我们配置了Value相关的规则,反而在每次存取时,需要自己手动的将Value转成字符串(如JSON化)进行存储.
4.现在我们可以进入测试阶段了,通过redisTemplate.opsForXXX()来获得操作redis的具体对象.
5.一些常见的操作测试.
package com.example.redistemplate.test_redis_template;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;
import java.util.List;
import java.util.Set;
@Slf4j
@SpringBootTest
public class Test2 {
//这个内容,只有springboot2.4.5才有2.7没有,或者有改名字,用的时候要注意
@Autowired
private RedisTemplate redisTemplate;
/**
* 测试存储键值对
*/
@Test
public void testString() {
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set("city1", "be1ijing");
System.out.println(valueOperations.get("city1"));
}
/**
* 测试存储hash对象
*/
@Test
public void testHash() {
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.put("person", "name", "涛涛呀");
hashOperations.put("person", "age", "18");
hashOperations.put("person", "nick", "绝绝子");
String age = (String) hashOperations.get("pserson", "age");
//获得hash中所有的键
Set keys = hashOperations.keys("person");
hashOperations.keys("person");
for (Object key : keys) {
System.out.println(key);
}
//获得hash中所有的值
List values = hashOperations.values("person");
for (Object value : values) {
System.out.println(value);
}
//PS:for迭代器.可以遍历set或者list
}
/**
* 操作List类型的数据
*/
@Test
public void testList() {
ListOperations listOperations = redisTemplate.opsForList();
//存值
//存一个
listOperations.leftPush("myList", "one");
//存多个
listOperations.leftPushAll("myList", "two", "three");
//取值
List<String> myList = listOperations.range("myList", 0, -1);
for (Object element : myList) {
log.info("element:{}", element);
}
//获得队列长度
Long size = listOperations.size("myList");
log.info("队列长度:{}", size.intValue());
for (int i = 0; i < size.intValue(); i++) {
//出队列
String element = (String) listOperations.rightPop("myList");
log.info("取出的数据:{}", element);
}
}
/**
* 操作Set类型的数据
*/
@Test
public void testSet() {
SetOperations<Object, String> setOperations = redisTemplate.opsForSet();
//存值
setOperations.add("myset", "a", "b", "c");
//取值
Set<String> myset = setOperations.members("myset");
for (String string : myset) {
System.out.println(string);
}
//删除成员
setOperations.remove("myset", "a", "b");
}
/**
* 操作ZSet类型的数据
*/
@Test
public void testZSet() {
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//存值
zSetOperations.add("myZset", "a", 10.0);
zSetOperations.add("myZset", "b", 10.0);
zSetOperations.add("myZset", "c", 9.0);
zSetOperations.add("myZset", "a", 10.0);
//取值
Set<String> myZset = zSetOperations.range("myZset", 0, -1);
for (String s : myZset) {
log.info("取出来的元素:{}", s);
}
//修改分数
zSetOperations.incrementScore("myZset", "b", 100.0);
//删除成员
zSetOperations.remove("myZset", "a", "b");
//取值
myZset = zSetOperations.range("myZset", 0, -1);
for (String s : myZset) {
log.info("取出来的元素:{}", s);
}
}
/**
* 通用操作,针对不同的数据类型都可以操作
*/
@Test
public void testCommon(){
//获取redis中所有的key
Set<String> keys = redisTemplate.keys("*");
for (String key:keys){
log.info("redis中的key:{}",key);
}
//判断某个key是否存在
Boolean itcastExist = redisTemplate.hasKey("itcast");
log.info("itcastExist是否存在:{}",itcastExist);
//删除指定key
// redisTemplate.delete("xxxx");
//获取指定key对应的value的数据类型
DataType myZsetType = redisTemplate.type("myZset");
log.info("myZsetType的类型:{}",myZsetType);
}
}
6.实际使用代码片段举例.将手机验证码保存在redis中
/** 发送手机验证码的时候存入redis */
redisTemplate.opsForValue().set(phone,captch,5, TimeUnit.MINUTES);
/** 登录/注册时,从redis中取出验证码进行比对 */
String captchInSession = (String)redisTemplate.opsForValue().get(loginVo.getPhone());
//进行验证码的比对,比对失败返回错误
if (captchInSession == null || !captchInSession.equals(loginVo.getCaptch())) {
return R.error("验证码错误!");
}
/** 比对成功之后,将之删除 */
redisTemplate.delete(loginVo.getPhone());
(扩展:配置文件预览------------------------------)
1.确认SpringBoot版本号为2.4.5.
2.查找External Libraries.
3.找到
org.springframework.boot.spring-boot-autoconfigure->spring.factoris->查找关键字redis->ctrl+左键点击第一个跳转.
4.可以看到spring帮我们自动配置了
RedisTemplate.
5.然后我们可以对比一下.我们在
2.7.0版本中相同的文件中搜索关键字redis,则找不到该配置项.
完.