Spring Data Redis的简单使用

355 阅读2分钟

简单介绍一下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的具体对象. image.png

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. image.png 2.查找External Libraries. image.png 3.找到org.springframework.boot.spring-boot-autoconfigure->spring.factoris->查找关键字redis->ctrl+左键点击第一个跳转. image.png 4.可以看到spring帮我们自动配置了RedisTemplate. image.png 5.然后我们可以对比一下.我们在2.7.0版本中相同的文件中搜索关键字redis,则找不到该配置项. image.png

完.