四、点赞,排行榜

文章目录

      • 点赞
      • 排行榜

官方命令文档:https://redis.io/commands/

点赞

需求:

  • 同一个用户只能点赞一次,再次点击则取消点赞
  • 如果当前用户已经点赞,则点赞按钮高亮显示(前端已实现,判断字段Blog类的isLike属性)
  • redis实现点赞数量

1.在Blog 添加一个字段

@TableField(exist = false)
private Boolean isLike;

2.代码

/**
 * 点赞方法
 */
@Override
public Result likeBlog(Long id) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();
    // 2.判断当前登录用户是否已经点赞
    String key = "blog:liked:" + id;
    Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
    if (score == null) {
        // 3.如果未点赞,可以点赞
        // 3.1.redis赞数 + 1
        Long count= redisTemplate.opsForValue().increment(key);
        // 3.2.保存用户到Redis的set集合  zadd key value score
        if (count!=null) {
            stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());
        }
    } else {
        // 4.如果已点赞,取消点赞
        // 4.1.redis点赞数 -1
        Long count = redisTemplate.opsForValue().decrement(key);
        // 4.2.把用户从Redis的set集合移除
        if (count!=null) {
            stringRedisTemplate.opsForZSet().remove(key, userId.toString());
        }
    }
    return Result.ok();
}

/**
 * 判断当前用户是否点赞
 */
private void isBlogLiked(Blog blog) {
    // 1.获取登录用户
    UserDTO user = UserHolder.getUser();
    if (user == null) {
        // 用户未登录,无需查询是否点赞
        return;
    }
    Long userId = user.getId();
    // 2.判断当前登录用户是否已经点赞
    String key = "blog:liked:" + blog.getId();
    Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
    blog.setIsLike(score != null);
}

排行榜

需求:

  • 在用户点赞基础上,根据点赞时间实现一个排行榜,显示前五位点赞的用户头像
    在这里插入图片描述

1.代码

/**
 * 点赞排行榜
 */
@Override
public Result queryBlogLikes(Long id) {
    String key = "blog:liked:" + id;
    // 1.查询top5的点赞用户 zrange key 0 4
    Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
    if (top5 == null || top5.isEmpty()) {
        return Result.ok(Collections.emptyList());
    }
    // 2.解析出其中的用户id
    List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
    String idStr = StrUtil.join(",", ids);
    // 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)
    List<UserDTO> userDTOS = userService.query()
            .in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list()
            .stream()
            .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
            .collect(Collectors.toList());
    // 4.返回
    return Result.ok(userDTOS);
}

有5个用户id,用in做查询结果不保证顺序,会变成12345
select * from user where id in (5,4,3,2,1)
要想保住顺序要加上排序条件
select * from user where id in (5,4,3,2,1) order by FIELD(id,5,4,3,2,1)

你可能感兴趣的:(redis,java,数据库,redis,点赞,排行榜)