• in(...) 可能会让你排查Bug到崩溃,哈哈哈


    前言:今天在做项目的时候发现了一个Bug,记录下来

    ​ 本来是要实现Top5,根据时间显示点赞的用户信息

    ​ (谁越早点赞,谁的显示就考前排)

    我在redis里面是用sortedSet记录

    key: 博客id

    value:用户id

    并且value对应的score是 时间戳

    这样就可以实现根据谁越早点赞进行顺序排序

    本以为这样就可以了…🤔🤔🤔


    String key=RedisConstants.BLOG_LIKED_KEY+id;
            Set<String> top5 = redisTemplate.opsForZSet().range(key, 0L, 4L);
            //避免空指针
            if(top5==null || top5.isEmpty()){
                return Result.ok(Collections.emptyList());
            }
            List<Long> userIds = top5.stream().map(Long::valueOf).collect(Collectors.toList());
            List<UserDTO> userDTOS = userService.listByIds(userIds)
                    .stream()
                    .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                    .collect(Collectors.toList());
            return Result.ok(userDTOS);
    
    //简单看一下,这个是业务代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    看似没有问题,但问题出现在了 sql 语句上

    这个业务代码对应的sql语句

    -- 假设用户id为5的点赞时间在用户id为1的点赞时间的前面
    select 
    	xxx
    from tb_user
    where id in(5,1)   
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题就出在了 in(…)

    在in里面查询的顺序可不是按照谁写在前谁写在后就先查顺

    in里面根据id查询是乱序查询的

    所以这就导致了返回结果的乱序现象

    -- 假设用户id为5的点赞时间在用户id为1的点赞时间的前面
    select 
    	xxx
    from tb_user
    where id in(5,1) 
    order by Field(id,5,1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    //对应的业务代码如下
    String key=RedisConstants.BLOG_LIKED_KEY+id;
            Set<String> top5 = redisTemplate.opsForZSet().range(key, 0L, 4L);
            //避免空指针
            if(top5==null || top5.isEmpty()){
                return Result.ok(Collections.emptyList());
            }
            List<Long> userIds = top5.stream().map(Long::valueOf).collect(Collectors.toList());
            String ids = StrUtil.join(",", userIds);
            List<UserDTO> userDTOS = userService.query()
                    .in("id",userIds)
                    .last("ORDER BY FIELD(id,"+ids+")") //自定义SQL语句
                    .list()
                    .stream()
                    .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                    .collect(Collectors.toList());
            return Result.ok(userDTOS);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    MySQL索引
    热迁移中VirtIO-PCI设备的配置空间处理
    教程 | Datavines 自定义数据质量检查规则(Metric)
    ROS学习——利用电脑相机标定
    医学图像分割之--Tversky Loss
    Windows平台下私有云盘搭建
    Excel快速对齐表格的中姓名(两个字姓名和三个字姓名对齐)
    uni-app——項目day01
    java 多线程&wait条件发生变化与使用while的必要性——77
    web前端期末大作业——网页制作基础大二dw作业——动画漫展学习资料电影模板(6页)
  • 原文地址:https://blog.csdn.net/C_x_330/article/details/127746930