黑马点评12-实现好友关注/取关功能,查看好友共同关注列表

好友关注

数据模型

数据库中的tb_follow记录博主与粉丝的关系

在这里插入图片描述

tb_follow表对应的实体类

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_follow")
public class Follow implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 用户id*/private Long userId;/*** 关联的用户id*/private Long followUserId;/*** 创建时间*/private LocalDateTime createTime;
}

是否关注/关注/取关

需求: 在探店图文的详情页面中,可以查看用户是否关注了笔记博主,用户也可以手动关注/取消关注发布笔记的作者

在这里插入图片描述

第一步: 在FollowController层中编写判断是否关注关注/取关的两个方法

@RestController
@RequestMapping("/follow")
public class FollowController {@Resourceprivate IFollowService followService;// 判断当前用户是否关注了笔记博主,参数是发布笔记的博主Id@GetMapping("/or/not/{id}")public Result isFollow(@PathVariable("id") Long followUserId) {return followService.isFollow(followUserId);}// 实现取关/关注,参数是发布笔记的博主Id以及是否关注(true表示关注,false表示取关)@PutMapping("/{id}/{isFollow}")public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFellow) {return followService.follow(followUserId,isFellow);}
}

第二步: 在FellowServiceImp中来编写具体的业务逻辑

  • 判断当前用户是否关注了笔记博主: 将请求参数携带的发布笔记的博主Id和当前登陆的用户Id作为条件去数据库中查询是否有对应的记录
  • 关注和取消关注: 请求参数中的true(关注)/fasle(取关),关注是将用户和博主的关联信息保存到数据库,取关即将他们的关联信息从数据库移除,避免堆积数据
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {@Overridepublic Result isFollow(Long followUserId) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();// 查询tb_follow表判断当前用户是否关注了该笔记的博主queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);// 没必要查询出具体数据,只需要判断数据存不存在即可//select count(*) from tb_follow where user_id = ? and follow_user_id = ?int count = this.count(queryWrapper);return Result.ok(count > 0);}@Overridepublic Result follow(Long followUserId, Boolean isFellow) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();// 判断用户是要关注还是取关,true表示关注,false表示取关if (isFellow) {// 关注则将用户和笔记博主的关联信息保存到数据库Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);save(follow);} else {// 取关则将用户和博主的关联信息从数据库中移除,避免数据库中堆积大量数据//delete from tb_follow where user_id = ? and follow_user_id = ?LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);remove(queryWrapper);}return Result.ok();}
}

共同关注

需求:当我们点击博主用户头像时进入到详情页,可以查看到博主发布的笔记以及用户和博主的好友共同关注列表

在这里插入图片描述

第一步: 在UserController中编写查询博主信息的方法

@GetMapping("/{id}")
public Result queryUserById(@PathVariable("id") Long userId) {// 查询详情User user = userService.getById(userId);if (user == null) {// 查不到返回空return Result.ok();}// 查到则转为userDTO对象UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);// 返回查询到的数据return Result.ok(userDTO);
}

第二步: 在BlogController中编写分页查询博主发布的所有笔记的方法

// 根据博主id查询博主的探店笔记
@GetMapping("/of/user")
public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current, @RequestParam("id") Long id) {LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();// 根据博主id查询用户信息queryWrapper.eq(Blog::getUserId, id);Page<Blog> pageInfo = new Page<>(current, SystemConstants.MAX_PAGE_SIZE);blogService.page(pageInfo, queryWrapper);// 获取查询到的所有用户信息List<Blog> records = pageInfo.getRecords();return Result.ok(records);
}// 根据博主id查询博主的探店笔记
@GetMapping("/of/user")
public Result queryBlogByUserId(@RequestParam(value = "current", defaultValue = "1") Integer current,@RequestParam("id") Long id) {// 根据博主id查询用户信息Page<Blog> page = blogService.query().eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));// 获取查询到的所有用户信息List<Blog> records = page.getRecords();return Result.ok(records);
}

第三步: 修改关注/取关的逻辑,以follows:userId作为Set集合的Key,存放当前用户关注的所有博主Id

  • 关注/取关: 将关注的博主Id放到当前登陆用户关注的Set集合中,取关就是将关注的博主Id从当前登陆用户的Set集合中移除
  • 共同关注:通过SINTER key1 key2查询登陆用户的Set集合和其关注博主的Set集合中元素的交集
@Resource
private StringRedisTemplate stringRedisTemplate;
@Service
public class FollowServiceImpl extends ServiceImpl<FollowMapper, Follow> implements IFollowService {@Overridepublic Result follow(Long followUserId, Boolean isFellow) {// 获取当前登录的用户IdLong userId = UserHolder.getUser().getId();String key = "follows:" + userId;// 判断用户是要关注还是取关,true表示关注,false表示取关if (isFellow) {// 关注则将用户和笔记博主的关联信息保存到数据库Follow follow = new Follow();follow.setUserId(userId);follow.setFollowUserId(followUserId);boolean iSsuccess = save(follow);// 如果更新成功则将关联信息也写入Redis,key是当前的用户id,value就是关注的博主idif (iSsuccess) {stringRedisTemplate.opsForSet().add(key, followUserId.toString());}} else {// 取关则将用户和博主的关联信息从数据库中移除,避免数据库中堆积大量数据//delete from tb_follow where user_id = ? and follow_user_id = ?LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Follow::getUserId, userId).eq(Follow::getFollowUserId, followUserId);boolean iSsuccess = remove(queryWrapper);// 如果取关成功则将关联的博主Id从当前登陆用户的set集合中移除if (iSsuccess){stringRedisTemplate.opsForSet().remove(key,followUserId.toString());}}return Result.ok();} 
}

第四步: 编写控制器方法,查看登陆用户和其关注博主的好友共同关注列表

@GetMapping("/common/{id}")
public Result followCommons(@PathVariable Long id){return followService.followCommons(id);
}
@Resource
private IUserService userService;
@Override
public Result followCommons(Long id) {// 获取当前登陆用户的idLong userId = UserHolder.getUser().getId();// // 获取当前登陆对应的set集合的keyString key1 = "follows:" + userId;// 获取当前登陆用户关注博主所对应的set集合的keyString key2 = "follows:" + id;// 对当前登陆用户和其关注博主的Set集合取交集Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key1, key2);// 无交集就返回个空的List集合if (intersect == null || intersect.isEmpty()) {return Result.ok(Collections.emptyList());}// 将String类型的用户id转化为Long类型的用户id然后使用List集合收集List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());// 根据ids集合中的用户id去数据库中查询登陆用户和博主共同关注的用户信息并封装成UserDto对象,最后存入List集合中返回List<UserDTO> userDTOS = userService.listByIds(ids).stream().map(user ->BeanUtil.copyProperties(user, UserDTO.class)).collect(Collectors.toList());return Result.ok(userDTOS);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/165071.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第三十二天| 122 买卖股票的最佳时机 || 55 跳跃游戏 45 跳跃游戏 ||

目录 122 买卖股票的最佳时机 || 55 跳跃游戏 45 跳跃游戏 || 122 买卖股票的最佳时机 || 设置变量now代表此时买入的股票&#xff0c;为赋值为Integer.MAX_VALUE&#xff0c;遍历prices数组&#xff0c;有如下两种情况&#xff1a; 如果比now小说明不能售出&#xff0c;可以…

关于unicloud云对象或云函数获取时间不对的问题

话不多说&#xff0c;直接上代码&#xff1a; function timeWeekFormat() { //定义一个日期对象; var dateTime getOffsetDate(8); //获得系统年份; var year dateTime.getFullYear(); //获得系统月份; var month dateTime.getMonth() 1; //获…

栈和队列的OJ题--12.括号匹配

12.括号匹配 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a;该题比较简单&#xff0c;是对栈特性很好的应用&#xff0c;具体操作如下&#xff1a;循环遍历String中的字符&#xff0c;逐个取到每个括号&#xff0c;如果该括号是&#xff1a;1. …

Git工作流和Commit规范

Git大家都非常熟悉了&#xff0c;就不做过多介绍&#xff0c;但是如何用好Git、如何进行合理的分支开发、Merge你是否有一个规范流程呢&#xff1f;&#x1f4a4; 不论是一个团队一起开发一个项目&#xff0c;还是自己独立开发一个项目&#xff0c;都少不了要和Git打交道&…

【NGINX--5】身份验证

1、HTTP 基本身份验证 需要通过 HTTP 基本身份验证保护应用或内容。 生成以下格式的文件&#xff0c;其中的密码使用某个受支持的格式进行了加密或哈希处理&#xff1a; # comment name1:password1 name2:password2:comment name3:password3第一个字段是用户名&#xff0…

紫光展锐V8821荣获“中国芯”重大创新突破产品奖

近日&#xff0c;“中国芯”优秀产品评选落下帷幕&#xff0c;紫光展锐首颗5G IoT-NTN卫星通信SoC芯片V8821凭借在卫星通信前沿领域的技术创新&#xff0c;从285家芯片企业、398款芯片产品中脱颖而出&#xff0c;荣获第十八届“中国芯”年度重大创新突破产品奖。 “中国芯”优…

ReentrantLock源码解析

ReentrantLock源码解析 文章目录 ReentrantLock源码解析一、ReentrantLock二、ReentrantLock 的 Sync、FairSync、NonfairSync2.1 Sync、FairSync、NonfairSync2.2 NonfairSync 下的 tryAcquire2.3 FairSync下的 tryAcquire2.4 tryRelease 三、lock.lock()3.1 NonfairSync.lock…

优橙内推青海专场——5G网络优化(中高级)工程师

可加入就业QQ群&#xff1a;801549240 联系老师内推简历投递邮箱&#xff1a;hrictyc.com 内推公司1&#xff1a;浙江明讯网络技术有限公司 内推公司2&#xff1a;南京华苏科技有限公司 内推公司3&#xff1a;杭州华星创业通信技术有限公司 浙江明讯网络技术有限公司 浙江明…

4.常见面试题--操作系统

特点&#xff1a;并发性、共享性、虚拟性、异步性。 Windows 和 Linux 内核差异 对于内核的架构⼀般有这三种类型&#xff1a; ● 宏内核&#xff0c;包含多个模块&#xff0c;整个内核像⼀个完整的程序&#xff1b; ● 微内核&#xff0c;有⼀个最⼩版本的内核&#xff0…

名字大却不中用的AI大模型,名不副实

这两天 OpenAI 团队&#xff08; ChatGPT 公司&#xff09;的戏比较多&#xff0c;两三天的功夫&#xff0c;剧情发展都超出了 OpenAI 首席科学家的预期&#xff0c;目前来看&#xff0c;微软还是最大的赢家。这是个引子&#xff0c;这个话题&#xff0c;网络上早已传烂了&…

云安全之盾:ZStack 云主机安全防护解决方案全方位保护云环境

随着云计算的蓬勃发展&#xff0c;网络威胁愈发复杂&#xff0c;涵盖了从勒索病毒到APT攻击的各种威胁类型。在这一风云变幻的网络安全环境下&#xff0c;云主机安全不再仅仅是一个选项&#xff0c;它是信息系统安全的核心要素。云轴科技ZStack 云主机安全防护解决方案是为了满…

6.3.WebRTC中的SDP类的结构

在上节课中呢&#xff0c;我向你介绍了sdp协议&#xff0c; 那这节课呢&#xff0c;我们再来看看web rtc中。是如何存储sdp的&#xff1f;也就是sdp的类结构&#xff0c;那在此之前呢&#xff1f;我们先对sdp的内容啊&#xff0c;做一下分类。因为在上节课中呢&#xff0c;虽然…

Python+jieba+wordcloud实现文本分词、词频统计、条形图绘制及不同主题的词云图绘制

目录 序言&#xff1a;第三方库及所需材料函数模块介绍分词词频统计条形图绘制词云绘制主函数 效果预览全部代码 序言&#xff1a;第三方库及所需材料 编程语言&#xff1a;Python3.9。 编程环境&#xff1a;Anaconda3&#xff0c;Spyder5。 使用到的主要第三方库&#xff1a;…

python之pyqt专栏1-环境搭建

#python pyqt# python&#xff1a;3.11.6 pycharm&#xff1a;PyCharm Community Edition 2023.2.5 pyqt6 python安装 官网下载&#xff1a;Python Releases for Windows | Python.org pycharm社区版安装 官网地址&#xff1a;Download PyCharm: Python IDE for Professional…

golang学习笔记——创建项目

创建项目 从Go 1.8开始&#xff0c;将GOPATH设置为环境变量不是必需的。如果我们没有设置一个&#xff0c;Go使用默认的GOPATH为$HOME/go。可以使用go env查看环境变量信息。 创建项目 # 创建项目目录 mkdir helloLog cd helloLog # 使用go mod初始化项目,生成go.mod文件 go…

TikTok shop印尼重启电商征程:与当地平台合作开启新篇章!——站斧浏览器

经历了一个半月的间隔&#xff0c;TikTok Shop成功重返印度尼西亚市场。据国际媒体报道&#xff0c;TikTok计划通过与印尼本地电子商务平台的合作&#xff0c;重启其在该国的电商业务。 Temmy Satya Permana&#xff0c;印尼合作社和中小企业部的官员&#xff0c;证实了这一重…

【广州华锐互动】VR线上课件制作软件满足数字化教学需求

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在教学领域的应用逐渐成为趋势。其中&#xff0c;广州华锐互动开发的VR线上课件制作软件更是备受关注。这种工具为教师提供了便捷的制作VR课件的手段&#xff0c;使得VR教学成为可能&#xff0c;极大地丰…

thinkphp6 不支持:redis错误

起因&#xff1a; 使用 redis 时候&#xff0c;thinkphp 报错。 解决方法&#xff1a; 打开 php.ini 文件&#xff0c;增加 extensionphp_redis.dll 即可

Java架构师发展方向和历程

目录 1 导论2 架构师的三观培养3 架构师的遇到的困难4 架构师职责5 架构师之路6 架构师的发展方向7 应用领域架构师8 业务架构师9 系统架构师和企业架构师10 技术路线和演进规划11 一线大厂的技术生态拓张案例12 如何推进项目落地想学习架构师构建流程请跳转:Java架构师系统架…

CUDA与GPU编程

文章目录 CUDA与GPU编程1. 并行处理与GPU体系架构1.1 并行处理简介1.1.1 串行处理与并行处理的区别1.1.2 并行处理的概念1.1.3 常见的并行处理 1.2 GPU并行处理1.2.1 GPU与CPU并行处理的异同1.2.2 CPU的优化方式1.2.3 GPU的特点 1.3 环境搭建 CUDA与GPU编程 1. 并行处理与GPU体…