第14章 SpringBoot集成Redis列表

Redis 中列表(List)类型是用来存储多个有序的字符串,一个列表最多可以存储40亿个字符串元素。我们可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表等等。列表是一种比较灵活的数据结构,可以充当栈和队列的角色,在实际开发中有很多应用场景。

我们借助上一章节的工程 “SpringBootRedisCacheDemo” 来简单介绍 Redis List的使用。

首先,我们将 Redis List的操作封装到 “RedisUtils” 类中。

    // 向List的左端缓存数据
    public <T> long setCacheListLeft(String key, T value){
        Long count = redisTemplate.opsForList().leftPush(key, value);
        return count == null ? 0 : count;
    }

    // 批量向List的左端缓存数据
    public <T> long setCacheListLeft(String key, List<T> values) {
        Long count = redisTemplate.opsForList().leftPushAll(key, values);
        return count == null ? 0 : count;
    }

    // 向List的右端缓存数据
    public <T> long setCacheListRight(String key, T value){
        Long count = redisTemplate.opsForList().rightPush(key, value);
        return count == null ? 0 : count;
    }

    // 批量向List的右端缓存数据
    public <T> long setCacheListRight(String key, List<T> values) {
        Long count = redisTemplate.opsForList().rightPushAll(key, values);
        return count == null ? 0 : count;
    }

    // 获取List中指定索引 index 的数据
    public <T> T getCacheListItemIndex(String key, int index){
        ListOperations<String, T> operations = redisTemplate.opsForList();
        return operations.index(key,index);
    }

    // 获得List中的缓存数据
    public <T> List<T> getCacheList(String key) {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    // 获得List中指定长度的缓存数据
    public <T> List<T> getCacheList(String key, int length) {
        return redisTemplate.opsForList().range(key, 0, length);
    }

    // 获取List的长度
    public long getCacheListSize(String key){
        return redisTemplate.opsForList().size(key);
    }

    // 获取List中左端一个数据,这个数据会被移除
    public <T> T getCacheListItemLeft(String key){
        ListOperations<String, T> operations = redisTemplate.opsForList();
        return operations.leftPop(key);
    }

    // 获取List中右端一个数据,这个数据会被移除
    public <T> T getCacheListItemRight(String key){
        ListOperations<String, T> operations = redisTemplate.opsForList();
        return operations.rightPop(key);
    }

    // 删除List中的缓存数据
    public <T> boolean removeCacheListItem(String key, T value){
        return redisTemplate.opsForList().remove(key,0,value) > 0;
    }

接下来,我们增加一个 “RedisTestController” 类进行测试

package com.demo.controller;

import com.demo.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/redis")
public class RedisTestController {

    @Autowired
    private RedisUtils redisUtils;

    private final static String RedisListLeftCacheKey = "RedisListLeftCacheKey";
    private final static String RedisListRightCacheKey = "RedisListRightCacheKey";

    @RequestMapping("/left")
    public String list(Map<String, Object> map){

        // 批量添加
        List<String> data = Arrays.asList("小明", "小红", "小强","小华", "小丽", "小王","小李", "小张");
        redisUtils.setCacheListLeft(RedisListLeftCacheKey, data);

        // 全部展示
        List<String> list = redisUtils.getCacheList(RedisListLeftCacheKey);
        map.put("list", list);

        return "redis";
    }

    @RequestMapping("/leftAdd")
    public String leftAdd(Map<String, Object> map){

        // 单独添加
        redisUtils.setCacheListLeft(RedisListLeftCacheKey, "张三");

        // 全部展示
        List<String> list = redisUtils.getCacheList(RedisListLeftCacheKey);
        map.put("list", list);

        return "redis";
    }
    
}

接下来,我们修改 “resources\static\index.html” 和增加 “resources\templates\redis.html” 视图文件

<a href="/student/list">/student/list</a>
<br />
<a href="/student/list2">/student/list2</a>
<br />
<a href="/redis/left">/redis/left</a>
<!doctype html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>redis</title>
</head>
<body>

<div th:each="item:${list}">
    <p th:text="${item}"></p>
</div>

<div>
    <p><a href="/redis/leftAdd">/redis/leftAdd</a></p>
</div>

</body>
</html>

接下来,我们测试一下从左端添加缓存数据

我们查看一下Redis里面的缓存数据

请注意,列表中的顺序。

接下来,我们点击 “redis/leftAdd” 向列表中添加一个数据。

我们查看一下Redis里面的缓存数据

注意,新加入的数据在 “左” 端,之前加入的数据在 “右” 端。

接下来,我们测试一下从右端添加缓存数据

    @RequestMapping("/right")
    public String right(Map<String, Object> map){

        // 批量添加
        List<String> data = Arrays.asList("小明", "小红", "小强","小华", "小丽", "小王","小李", "小张");
        redisUtils.setCacheListRight(RedisListRightCacheKey, data);

        // 全部展示
        List<String> list = redisUtils.getCacheList(RedisListRightCacheKey);
        map.put("list", list);

        return "redis";
    }

    @RequestMapping("/rightAdd")
    public String rightAdd(Map<String, Object> map){

        // 单独添加
        redisUtils.setCacheListRight(RedisListRightCacheKey, "张三");

        // 全部展示
        List<String> list = redisUtils.getCacheList(RedisListRightCacheKey);
        map.put("list", list);

        return "redis";
    }

接下来,我们修改 “resources\static\index.html” 和 “resources\templates\redis.html” 视图文件

<a href="/student/list">/student/list</a>
<br />
<a href="/student/list2">/student/list2</a>
<br />
<a href="/redis/left">/redis/left</a>
<br />
<a href="/redis/right">/redis/right</a>
<div th:each="item:${list}">
    <p th:text="${item}"></p>
</div>

<div>
    <p><a href="/redis/leftAdd">/redis/leftAdd</a></p>
</div>

<div>
    <p><a href="/redis/rightAdd">/redis/rightAdd</a></p>
</div>

接下来,我们测试一下

我们查看一下Redis里面的缓存数据

根我们之前“left”写入的顺序正好相反了。

接下来,我们继续测试增加一个数据。

这就是List中左端插入和右端插入的顺序问题了。 如果我们想要获取List中某个数据的话,可以通过其索引调用 “getCacheListItemIndex” 方法来获取。接下来我们介绍 “pop” 方法,它可以从List两端获取元素,并删除该元素,类似于 “出栈” 的操作。

@RequestMapping("/leftPop")
    public String leftPop(Map<String, Object> map){

        // 左端出栈
        String data = redisUtils.getCacheListItemLeft(RedisListLeftCacheKey);
        map.put("info", data);

        // 全部展示(刚刚出栈的就没有了)
        List<String> list = redisUtils.getCacheList(RedisListLeftCacheKey);
        map.put("list", list);

        return "redis";
    }

    @RequestMapping("/rightPop")
    public String rightPop(Map<String, Object> map){

        // 右端出栈
        String data = redisUtils.getCacheListItemRight(RedisListRightCacheKey);
        map.put("info", data);

        // 全部展示(刚刚出栈的就没有了)
        List<String> list = redisUtils.getCacheList(RedisListRightCacheKey);
        map.put("list", list);

        return "redis";
    }

接下来,我们修改 “resources\static\index.html” 和 “resources\templates\redis.html” 视图文件

<a href="/student/list">/student/list</a>
<br />
<a href="/student/list2">/student/list2</a>
<br />
<a href="/redis/left">/redis/left</a>
<br />
<a href="/redis/right">/redis/right</a>
<br />
<a href="/redis/leftPop">/redis/leftPop</a>
<br />
<a href="/redis/rightPop">/redis/rightPop</a>
<div th:each="item:${list}">
    <p th:text="${item}"></p>
</div>

<div>
    <p><a href="/redis/leftAdd">/redis/leftAdd</a></p>
</div>

<div>
    <p><a href="/redis/rightAdd">/redis/rightAdd</a></p>
</div>

<div th:if ="${info}">
    <p th:text="${info}"></p>
</div>

接下来,我们重新运行测试一下

我们再去Redis中核实一下

之前我们添加的“张三”已经没有了。

如果我们继续从左端 “pop” 数据的话,应该是 “小张” 这个缓存数据了,我们可以试一下。

剩下的从右端出栈的话,大家可以自己测试一下。

如果我们需要模拟列表“先进先出”的使用方式的话,应该是左“push”右“pop”的操作方式哦。

本工程完整代码下载: https://download.youkuaiyun.com/download/richieandndsc/89953228

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值