当前位置: 首页 > news >正文

用户关注功能

介绍

本文将介绍如何通过redis,mysql数据库实现用户关注,以及查看共同关注的功能。、

前置准备

创建一个tb_follow表,用于记录关注信息。

以及一个redis数据库。

实现思路

主要实现3个接口:

  • isFollow接口(进入up主页时调用):判断用户是否关注了当前up主,如果已经关注,返回true,否则返回false。
  • follow接口(点击关注按钮时调用):如果已经关注了该up,则取关,反之,关注up。
  • followCommons接口(点击共同关注按钮时调用):查看你和up都关注了哪些用户。

isFollow

controller

接收请求参数id(up主id),调用service中的业务逻辑。

@GetMapping("/or/not/{id}")publicResultisFollow(@PathVariableLongid){returnfollowService.isFollow(id);}

service

@OverridepublicResultisFollow(Longid){LonguserId=UserHolder.getUser().getId();longcount=query().eq("user_id",userId).eq("follow_user_id",id).count();returnResult.ok(count>0);}

业务逻辑
从上下文(threadlocal)中获取当前用户id,根据用户id和up主id在tb_follow中查询数据,返回数据count > 0,如果有数据则为true,否则为false。

follow

controller

接收请求参数id(up主id),isFollow(true代表执行关注,false代表执行取关),调用service中的业务逻辑。

@PutMapping("{id}/{isFollow}")publicResultfollow(@PathVariableLongid,@PathVariableBooleanisFollow){returnfollowService.follow(id,isFollow);}

service

@OverridepublicResultfollow(Longid,BooleanisFollow){LonguserId=UserHolder.getUser().getId();//判断当前用户是否关注Stringkey="follow:"+userId;if(isFollow){//关注,新增数据Followfollow=newFollow();follow.setUserId(userId);follow.setFollowUserId(id);booleanisSuccess=save(follow);if(isSuccess){//把关注用户的id放入redis的set集合中,key:follow:userId value:followUserIdstringRedisTemplate.opsForSet().add(key,id.toString());}}else{//取关,删除数据booleanisSuccess=update().eq("user_id",userId).eq("follow_user_id",id).remove();if(isSuccess){//把关注用户的id从redis的set集合中移除stringRedisTemplate.opsForSet().remove(key,id.toString());}}returnResult.ok();}

业务逻辑

  1. 从上下文(threadlocal)中获取当前用户id。
  2. 执行关注或取关
    关注:将信息写入follow实体(属性与tb_follow表字段一致),并写入数据库,如果操作成功,再放入redis的set集合中。
    取关:删除数据库信息,如果成功,再移除redis的set集合中的id。

followCommons

controller

接收请求参数id(当前查看up主的id)。

@GetMapping("/common/{id}")publicResultfollowCommons(@PathVariableLongid){returnfollowService.followCommons(id);}

service

@OverridepublicResultfollowCommons(Longid){LonguserId=UserHolder.getUser().getId();StringmyKey="follow:"+userId;StringtargetKey="follow:"+id;//求交集Set<String>intersect=stringRedisTemplate.opsForSet().intersect(myKey,targetKey);if(intersect==null||intersect.isEmpty()){//没有共同关注returnResult.ok("没有共同关注");}//解析id集合List<Long>commonIds=intersect.stream().map(Long::valueOf).collect(Collectors.toList());//查询用户List<User>users=userService.listByIds(commonIds);//转换为DTOList<UserDTO>userDTOS=users.stream().map(user->BeanUtil.copyProperties(user,UserDTO.class)).collect(Collectors.toList());returnResult.ok(userDTOS);}

业务逻辑

  1. 获取两者在redis中的key。
  2. 求两者交集。
    交集为空->直接返回结果
    有交集->解析出id集合
  3. 根据id集合查询用户,返回数据。

核心要点:

关注时将id放入redis中的set集合,优点:

查询效率Redis Set 的SINTER命令可以一次求出交集,时间复杂度 O(min(n,m)),非常高效
去重Set 自动去重,保证关注列表不重复
内存优化相比数据库查询,Redis 内存操作快几十倍
http://www.jsqmd.com/news/494846/

相关文章:

  • Git急救手册:30秒拯救误操作
  • Java面试高频考点MySQL索引优化与问题处理指南
  • 【从零开始学Java | 第十一篇】包、final、权限修饰符
  • 基于Simscape的双PID比例调速阀与比例溢流阀液压控制系统建模与仿真
  • 【路径规划】基于时空A星算法求解带时间约束的多机器人路径规划问题附matlab代码
  • 动静态库原理与ELF文件详解
  • 2026 年最新漏洞挖掘终极指南|从基础到精通,收藏这一篇足够
  • 【C++】C++设计心得--轮询、事件、异步
  • 2026年最值得用的降AI率工具实测:认准这几款就够了
  • 大模型函数调用(Function Calling)
  • 简单中文分词工具scws的安装和使用方法
  • 2026年深圳4G监控品牌优选:海康威视与大华权威评测与推荐
  • Flink知识点(一)|Flink中的双流关联
  • TCL发布会解析:Q9M Pro领衔,T7M系列双星登场,163吋Micro LED双曜压轴
  • 森林防火系统早期烟雾识别的误报率控制:面向测试工程师的实战指南
  • 【LLM基础】6. LLM 推理时的温度值、top_p、top_k等采样算法原理
  • 『NAS』将NAS变成单词收割机-QwertyLearner
  • 基于深度学习的表格识别技术:通过多模态预处理、神经网络分析和高精度OCR识别,实现复杂银行流水的自动化解析
  • 【第10篇】Mamba 100篇合集 · 从入门到天花板
  • 少走弯路:10个降AI率网站开源免费测评与推荐
  • java面试题总结2
  • LeetCode 1727.重新排列后的最大子矩阵:枚举矩形底边是哪一行 + 排序
  • 2026年塑料瓶粉碎机厂家实力榜TOP3,谁是行业领头羊?
  • 2026年主流论文降AI率工具实测:亲测有效的神器全在这
  • Windows系统漏洞MS17-010全解析
  • 一次签名毁掉数亿美元,深度拆解DeFi历史级漏洞
  • geocode.com.cn:经纬度查询省市县乡街道的地理编码服务
  • 花2千块法人号码核验百万条号码,结果一半是空号”:B端拓客的核验陷阱,该到头了,终于找到了个便宜的法人号码核验就是氪迹科技
  • 7-2 然后是几点
  • 2026年AI编程实战:如何用Gemini 3.1 Pro与国内镜像站提升开发效率