用于排队叫号系统的redis工具类

  1. 分析

排队叫号系统的队列数据变化很频繁,因此可以考虑使用redis的list结构存储某一队列的数据,与前端采用websocekt连接,后端主动推送数据给前端,避免频繁轮询造成资源浪费。
为了满足排队系统的需求,需要设计以下几个api:

  • 入队
  • 出队
  • 获取队列数据和队长
  • 允许某人中途离队(已知其信息,从队列中剔除)
  • 允许某人插队(在目标anchor前插队还是后插队)
  • 得到某人在队列中的位置

2 redis配置和Vo类代码

yml配置

  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    timeout: 3000
    jedis:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0

redis配置类

@EnableCaching
@Configuration
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.database}")
    private Integer database;
    @Value("${spring.redis.port}")
    private Integer port;
//  @Value("${spring.redis.password}")
//  private String pwd;

    @Primary
    @Bean(name = "jedisPoolConfig")
    @ConfigurationProperties(prefix = "spring.redis.pool")
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxWaitMillis(100000);
        return jedisPoolConfig;
    }

    @Bean
    public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setDatabase(database);
        // redisStandaloneConfiguration.setPassword(pwd);
        redisStandaloneConfiguration.setPort(port);
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        jpcb.poolConfig(jedisPoolConfig);
        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
        return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
    }

    /**
     * 配置redisTemplate针对不同key和value场景下不同序列化的方式
     *
     * @param factory Redis连接工厂
     * @return
     */
    @Primary
    @Bean(name = "redisTemplate")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        Jackson2JsonRedisSerializer redisSerializer = new Jackson2JsonRedisSerializer(PatientVo.class);
        template.setValueSerializer(redisSerializer);
        template.setHashValueSerializer(redisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

vo类代码:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PatientVo {
    private Long patientId;
    private Integer queueNum;
    private String patientName;
    private String patientGender;
}
  1. redis排队工具类

这里写的不好的地方在于没有判断捕获异常。

@Component
public class QueueUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 入队
     * @param roomCode 诊室编码
     * @param vo 病人vo对象
     */
    public  void addPatient2Queue(String roomCode, PatientVo vo) {
        redisTemplate.opsForList().rightPush(roomCode, vo);
    }

    /**
     * 队长
     * @param roomCode 诊室编码
     * @return Long长度
     */
    public  Long getQueueLength(String roomCode) {
        return redisTemplate.opsForList().size(roomCode);
    }

    // 获取队列数据
    public List getQueueData(String roomCode) {
        return redisTemplate.opsForList().range(roomCode, 0, -1);
    }

    // 某人中途离开队伍
    public  void leaveQueue(String roomCode, PatientVo patientVo) {
        redisTemplate.opsForList().remove(roomCode, 0, patientVo);
    }

    // 队首离队
    public  PatientVo headLeaveQueue(String roomCode) {
        PatientVo leftPop = redisTemplate.opsForList().leftPop(roomCode);
        return leftPop;
    }

    // 得到某人队列中的位置
    public  List getOnesPosition(String roomCode, PatientVo patientVo) {
        List queueData = getQueueData(roomCode);
        int myPositionBeforeNum = queueData.indexOf(patientVo);
        int myPosition = myPositionBeforeNum + 1;
        int size = queueData.size();
        // 当前排队res[0]人,您排在第res[1]位,前面还有res[2]位。
        List result = new ArrayList<>();
        result.add(size);
        result.add(myPosition);
        result.add(myPositionBeforeNum);
        return result;
    }

    // 插队操作
    public  void jumpAQueue(String roomCode, PatientVo jumpChecker, PatientVo targetChecker, Integer jumpType) {
        // 在target前面插队
        if (jumpType.equals(1)) {
            redisTemplate.opsForList().leftPush(roomCode, targetChecker, jumpChecker);
        }
        if (jumpType.equals(2)) {
            redisTemplate.opsForList().rightPush(roomCode, targetChecker, jumpChecker);
        }
    }
}
  1. 简单测试

测试代码

@Autowired
    private QueueUtil queueUtil;

    @GetMapping("/test/qu")
    private Result testQueueUtil() {
        long start = System.currentTimeMillis();
        List list = patientInfoService.list();
        for (int i = 0; i < 10; i++) {
            PatientInfo info = list.get(i);
            PatientVo vo = new PatientVo(info.getPatientId(),
                    info.getQueueNum(),
                    info.getPatientName(),
                    info.getPatientSex());
            queueUtil.addPatient2Queue("test", vo);
        }
        List queueData = queueUtil.getQueueData("test");
//      PatientVo jumpVo = new PatientVo(1999L, 2999, "test", "test");
//      PatientVo targetVo = new PatientVo(1058L, 2005, "冯秀娟", "女");
//      queueUtil.jumpAQueue("test", jumpVo, targetVo, 2);
//      List queueData = queueUtil.getQueueData("test");
        long end = System.currentTimeMillis();
        log.info("waste time: {}s", (float)(end - start) / 1000);
        return Result.success(queueData);
    }

测试结果图1:

用于排队叫号系统的redis工具类
测试结果图2:
用于排队叫号系统的redis工具类
然后测试一下插队功能,在冯秀娟后面插入test
查看RedisManager里的结果:
用于排队叫号系统的redis工具类
test成功插队。

Original: https://www.cnblogs.com/ceeSomething8/p/15935420.html
Author: cee_nil
Title: 用于排队叫号系统的redis工具类

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622727/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 《关于程序猿也得刷行测题的这一天》——第二章:行测题把握不住

    AS YOU CAN SEE,菜鸡程序猿经历了上次的社会毒打后,感到非常挫折。 在家除了睡,就是吃,除了吃,就是睡,除了睡,就是吃。。。。 好的,让我们继续回到程序猿找工作的问题。…

    数据结构和算法 2023年6月8日
    0165
  • 深入C++03:面向对象

    📕面向对象 类和对象、this指针 不用做太多笔记,都可以看初识C++的笔记; 记住👀:声明后面都要加” &#xFF1B;“,比如声明方法和变量还有…

    数据结构和算法 2023年6月12日
    0102
  • 哈希表(HashTable)

    哈希表 哈希表:也叫做散列表。是根据关键字和值(Key-Value)直接进行访问的数据结构。也就是说,它通过关键字 key 和一个映射函数 Hash(key) 计算出对应的值 va…

    数据结构和算法 2023年6月8日
    0123
  • leecode每日刷题3

    leecode每日刷题3 leecode每日刷题3 题目描述 反转字符串 &#x7F16;&#x5199;&#x4E00;&#x4E2A;&…

    数据结构和算法 2023年6月7日
    0114
  • 数据结构基础——线性表的基本操作

    基本结构 首先我们声明我们所使用的数据类型(也可不做此声明,后续的dataType换成你所用的类型即可) typedef int dataType; 定义基本数据结构,数组or链表…

    数据结构和算法 2023年6月12日
    0134
  • Timer和ScheduledThreadPoolExecutor的区别及源码分析

    Timer 基于单线程、系统时间实现的延时、定期任务执行类。具体可以看下面红色标注的代码。 Timer延时、定时任务的实现采用单线程,在主循环(mainLoop)中循环遍历任务队列…

    数据结构和算法 2023年6月8日
    0106
  • Typora

    安装包 点击即可下载上面那个好像不太行了,这个吧 主题(自己修改) nigt_new 自己修改的 user bash (主要是代码块方面的) whity 魔改 Original: …

    数据结构和算法 2023年6月7日
    090
  • 「周记」拓扑排序

    拓扑排序的英文名是 Topological sorting。拓扑排序要解决的问题是给一个图的所有节点排序。拓扑排序的目标是将所有节点排序,使得排在前面的节点不能依赖于排在后面的节点…

    数据结构和算法 2023年6月12日
    0101
  • 变量命名 函数命名 方法 Naming cheatsheet

    Naming things is hard. This sheet attempts to make it easier. Although these suggestions c…

    数据结构和算法 2023年6月16日
    0174
  • Codeforces1573B

    问题描述 给你两个数组,a数组里面是1 – 2n中的奇数任意顺序排列组成,b数组里面是1 – 2n中的奇数任意顺序排列组成。 问你最少需要多少次操作能让a的…

    数据结构和算法 2023年6月7日
    0119
  • G&GH05 删除文件和.gitignore

    平台: Windows 10 学习笔记 转载请注明出处 欢迎留言 本系列文章是 git & github 的入门教程. 本系列文章优势: 实际开发过程中, 我们经常会希望不…

    数据结构和算法 2023年6月12日
    0104
  • 分布式ID生成方案

    分布式ID策略 为什么要用分布式ID? 在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个 MySQL 主从同步读写分离也能对付。 但随着数据日渐增长,主从…

    数据结构和算法 2023年6月8日
    0142
  • Acm模板-计算几何(寄算几何)

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    数据结构和算法 2023年6月12日
    099
  • Java对象序列化和反序列化

    Java类的序列化和反序列化 序列化:指将对象转换为字节序列的过程,也就是将对象的信息转换成文件保存。 反序列化:将字节序列转换成目标对象的过程,也就是读取文件,并转换为对象。 几…

    数据结构和算法 2023年6月16日
    0101
  • 【设计模式】之桥接模式

    定义 桥接模式(Bridge Pattern)定义:将抽象化与实现化分离,使得双方可以独立变化。 当然定义什么的通常都晦涩难懂,咱们还是借助例子来理解。 举例 还是举个例子吧。 假…

    数据结构和算法 2023年6月12日
    0136
  • 排序算法-比较

    常用排序算法总结和对比 一张排序算法的比较图 相关术语解释 稳定:如果 a 原本在 b 前面,而 a=b,排序之后 a 仍然在 b 的前面; 不稳定:如果 a 原本在 b 的前面,…

    数据结构和算法 2023年6月12日
    0104
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球