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