• 黑马点评-关注和取关


     针对用户的操作:可以对用户进行关注和取消关注功能。

    实现思路:

    需求:基于该表数据结构,实现两个接口:

    • 关注和取关接口:用于数据库记录是否对该博主进行关注

    • 判断是否关注的接口:用于前端进行高亮显示

    关注是User之间的关系,是博主与粉丝的关系,数据库中有一张tb_follow表来标示:

     数据库存入一张关注表,用于记录的存储。

    FollowController

    1. //关注--//取消关注
    2. @PutMapping("/{id}/{isFollow}")
    3. public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFollow) {
    4. return followService.follow(followUserId, isFollow);
    5. }
    6. // 高亮显示
    7. @GetMapping("/or/not/{id}")
    8. public Result isFollow(@PathVariable("id") Long followUserId) {
    9. return followService.isFollow(followUserId);
    10. }

     FollowService

    1. // 数据库有记录则高亮显示
    2. @Override
    3. public Result isFollow(Long followUserId) {
    4. // 1.获取登录用户
    5. Long userId = UserHolder.getUser().getId();
    6. // 2.查询是否关注 select count(*) from tb_follow where user_id = ? and follow_user_id = ?
    7. Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();
    8. // 3.判断
    9. return Result.ok(count > 0);
    10. }
    11. // 关注和取关service
    12. @Override
    13. public Result follow(Long followUserId, Boolean isFollow) {
    14. // 1.获取登录用户
    15. Long userId = UserHolder.getUser().getId();
    16. String key = "follows:" + userId;
    17. // 1.判断到底是关注还是取关
    18. if (isFollow) {
    19. // 2.关注,新增数据
    20. Follow follow = new Follow();
    21. follow.setUserId(userId);
    22. follow.setFollowUserId(followUserId);
    23. boolean isSuccess = save(follow);
    24. } else {
    25. // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
    26. remove(new QueryWrapper()
    27. .eq("user_id", userId).eq("follow_user_id", followUserId));
    28. }
    29. return Result.ok();
    30. }

    共同关注 

    想要去看共同关注的好友,需要首先进入到这个页面,这个页面会发起两个请求

    1、去查询用户的详情

    2、去查询用户的笔记

     

    1. // UserController 根据id查询用户
    2. @GetMapping("/{id}")
    3. public Result queryUserById(@PathVariable("id") Long userId){
    4. // 查询详情
    5. User user = userService.getById(userId);
    6. if (user == null) {
    7. return Result.ok();
    8. }
    9. UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
    10. // 返回
    11. return Result.ok(userDTO);
    12. }
    13. // BlogController 根据id查询博主的探店笔记
    14. @GetMapping("/of/user")
    15. public Result queryBlogByUserId(
    16. @RequestParam(value = "current", defaultValue = "1") Integer current,
    17. @RequestParam("id") Long id) {
    18. // 根据用户查询
    19. Page page = blogService.query()
    20. .eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
    21. // 获取当前页数据
    22. List records = page.getRecords();
    23. return Result.ok(records);
    24. }

    接下来我们来看看共同关注如何实现:

    需求:利用Redis中恰当的数据结构,实现共同关注功能。在博主个人页面展示出当前用户与博主的共同关注呢。

    当然是使用我们之前学习过的set集合咯,在set集合中,有交集并集补集的api,我们可以把两人的关注的人分别放入到一个set集合中,然后再通过api去查看这两个set集合中的交集数据。

     

    我们先来改造当前的关注列表

    改造原因是因为我们需要在用户关注了某位用户后,需要将数据放入到set集合中,方便后续进行共同关注,同时当取消关注时,也需要从set集合中进行删除,主要是增添了一些Redis记录

    FollowServiceImpl

    1. @Override
    2. public Result follow(Long followUserId, Boolean isFollow) {
    3. // 1.获取登录用户
    4. Long userId = UserHolder.getUser().getId();
    5. String key = "follows:" + userId;
    6. // 1.判断到底是关注还是取关
    7. if (isFollow) {
    8. // 2.关注,新增数据
    9. Follow follow = new Follow();
    10. follow.setUserId(userId);
    11. follow.setFollowUserId(followUserId);
    12. boolean isSuccess = save(follow);
    13. if (isSuccess) {
    14. // 把关注用户的id,放入redis的set集合 sadd userId followerUserId
    15. stringRedisTemplate.opsForSet().add(key, followUserId.toString());
    16. }
    17. } else {
    18. // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
    19. boolean isSuccess = remove(new QueryWrapper()
    20. .eq("user_id", userId).eq("follow_user_id", followUserId));
    21. if (isSuccess) {
    22. // 把关注用户的id从Redis集合中移除
    23. stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
    24. }
    25. }
    26. return Result.ok();
    27. }

    具体的关注代码:

    FollowServiceImpl

    1. @Override
    2. public Result followCommons(Long id) {
    3. // 1.获取当前用户
    4. Long userId = UserHolder.getUser().getId();
    5. String key = "follows:" + userId;
    6. // 2.求交集
    7. String key2 = "follows:" + id;
    8. Set intersect = stringRedisTemplate.opsForSet().intersect(key, key2);
    9. if (intersect == null || intersect.isEmpty()) {
    10. // 无交集
    11. return Result.ok(Collections.emptyList());
    12. }
    13. // 3.解析id集合
    14. List ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());
    15. // 4.查询用户
    16. List users = userService.listByIds(ids)
    17. .stream()
    18. .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
    19. .collect(Collectors.toList());
    20. return Result.ok(users);
    21. }

    分析逻辑:

    首先我们写了两个实现,

    一个是关注与取关:通过对数据库的follow表的查询,来表示关注者和被关注的关系。

    另一个是进行follow表的查询,用于前端进行高亮展示。

    其次,我们通过redis进行共同关注

    【第一步】我们先改写了关注和取关的逻辑,主要是增添了redis的Set数据结构添加和删除。

    【第二步】利用Set的交集实现共同关注的功能。

    【反思】

    我们写的共同关注业务能使Redis和数据库一致嘛?显然在Redis不发生突然宕机的前提是会保证Redis和数据库的一致性。

    原因:我们是在改写数据库的同时也改写了Redis。

  • 相关阅读:
    Throwable异常
    ref、reactive、toRef、toRefs
    数云融合 | 旧叔讲文旅:数字化进程中功不可没的二维码
    基于Echarts实现可视化数据大屏大数据可视化
    书生·浦语大模型开源体系(四)作业
    java开源商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城
    el-table表格中加入输入框
    内核学习——1、list_head
    关于空洞填充和求重心
    绕过WAF(Web应用程序防火墙)--介绍、主要功能、部署模式、分类及注入绕过方式等
  • 原文地址:https://blog.csdn.net/abc123mma/article/details/127720830