前言

如题,该篇实践教程就是简单的抛砖引玉,通过实现一个简单的排队场景,带着大家熟悉下 redis里list数据结构的相关操作。

 

正文

 

在开始编码前,我们先简单了解下该篇实践教程实现 排队场景,

包括哪些功能:

1. 正常排队

2.队伍总人数

3.队伍信息

4.某人离开队伍

5.正常排队完离开队伍

6.某人在队伍的所在位置,前面人数,后面人数

7.插队 (道德不允许,咱们只是做个例子)

 

开始编码:

 

ps :怎么整合redis这篇文章就不介绍了,如果还不会的可以看我的这个系列的教程。

 

为了方便咱们的演示,直接通过写接口调接口的方式。

创建一个MyTestController.java,注入一下RedisTemplate:

/**
* @Author : JCccc
* @CreateTime : 2020/3/27
* @Description :
**/

@Controller
@RequestMapping("/test")
public class MyTestController {

@Autowired
private RedisTemplate redisTemplate;


}

1. 正常排队

/**
* 加入队伍
* @param userId
*/
@ResponseBody
@GetMapping("/addQueue")
public void addQueue(@RequestParam("userId") String userId) {
// redisTemplate.opsForList().leftPush("myQueue",userId);
redisTemplate.opsForList().rightPush("yourQueue",userId);
}

 

可以看到这个接口里面,我的代码有一行注释的,其实两行低吗都是往队伍里面去添加数据达到 排队加入队伍的功能。

而通过数据顺序来说,我选择使用rightPush,这样更能容易理解排队的原则,先进先出。

 

那么我们开始调用接口 /addQueue ,看看效果:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_redis

可以看到redis里面的数据,01 妥妥地加入到了队伍: 

 

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_排队_02

 

重复上面的操作,模拟出一个小队列数据,将02,03,04,05 也按顺序排队加入到队伍里,结果如:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_redis_03

2.队伍总人数

/**
* 队伍总人数
*/
@ResponseBody
@GetMapping("/queueCount")
public String queueCount() {
Long listSize = redisTemplate.opsForList().size("yourQueue");
return "队伍总人数:"+listSize;
}

调用接口,查看队伍总人数:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_springboot_04

 3.队伍信息

/**
* 队伍详情
*/
@ResponseBody
@GetMapping("/queueData")
public String queueData() {
List listData = redisTemplate.opsForList().range("yourQueue", 0, -1);
return listData.toString();
}

调用接口,查看队伍详情:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_list_05

 4.某人离开队伍

/**
* 离开队伍
* @param userId
*/
@ResponseBody
@GetMapping("/leaveQueue")
public void leaveQueue(@RequestParam("userId") String userId) {
Long removeNum = redisTemplate.opsForList().remove("yourQueue", 0, userId);
System.out.println(removeNum);
}

这个接口里面使用的方法,第二个参数,需要注意:

对于list数据其实是允许重复的,但是我们模拟的队列数据,给用户分配的userId保持唯一。

但是原有的remove方法使兼容了重复数据移除的场景,
当传入 0: 移除整个队列里的 目标值 ,也就是录入传入userId是01,

那么有一个也移除,有N个也移除,反正保证干干净净。

当传入小于0的数,如-1或者传入大于0的数,如1: 就是不同顺序去检查这个队伍,直到碰到第一个目标值,进行删除。 

 

调用接口,模拟 03 这个用户离开队伍:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_排队_06

结果:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_数据_07

5.正常排队完离开队伍

/**
* 默认离队,先进先出
*/
@ResponseBody
@GetMapping("/defaultLeaveQueue")
public void defaultLeaveQueue() {

redisTemplate.opsForList().leftPop("yourQueue");
}

当前队伍里面01排在最前面,所以当调用接口时,默认排完队离开的就是01,先进先出:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_list_08

结果:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_springboot_09

6.某人在队伍的所在位置, 前面人数,后面人数

/**
* 查看我自己的队列位置
* @param userId
*/
@ResponseBody
@GetMapping("/getMyPosition")
public void getMyPosition(@RequestParam("userId") String userId){
List listData = redisTemplate.opsForList().range("yourQueue", 0, -1);
int myPositionBeforeNum = listData.indexOf(userId);
int myPositionNum = listData.indexOf(userId)+1;
int size=listData.size();
System.out.println("所在位置前面人数:"+myPositionBeforeNum);
System.out.println("所在位置:"+myPositionNum);
System.out.println("所在位置后面人数:"+(size-myPositionNum));
}

调用接口,查看04所在队伍的位置,以及他前面还有多少人,后面还有多少人:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_redis_10

结果:

 

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_数据_11

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_排队_12

7.插队  

ps:有时候业务需要插队场景还是有需要的

/**
* 野蛮插队
* @param userId
* @param toUserId
*/
@ResponseBody
@GetMapping("/savageAction")
public void savageAction(@RequestParam("userId") String userId ,@RequestParam("toUserId") String toUserId,@RequestParam("type") String type){

//userId 插队人
//toUserId 被插队人
//before 插前面
//after 插后面
if ("before".equals(type)){
redisTemplate.opsForList().leftPush("yourQueue",toUserId,userId);
}
if ("after".equals(type)){
redisTemplate.opsForList().rightPush("yourQueue",toUserId,userId);
}
}

插队有分插前面和后面,调用接口,模拟一个新用户 2020 插队,插入到了04这个用户前面:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_redis_13

结果:

 

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_list_14

 再调用接口,模拟一个新用户 3003 插队,插入到了2020这个用户后面:

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_数据_15

结果:

 

(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九_数据_16

 

 

该篇就到此。