SpringBoot实现文章点赞功能
提示:今日是2024年的6月30日,未来的你看到这篇文章,希望你依旧快乐
文章目录
前言
首先在这里前缀部分我就不做要求了,比如说登录信息什么的
数据库表格
这里实现点赞功能,主要是围绕论坛项目完成的
user_info代表用户信息表
forum_article代表着文章信息表
user_message代表着点赞或者评论点赞发送信息表
like_record代表着用户点赞表
user_info用户信息表


forum_article文章信息表


user_message点赞评论信息发送表


like_record点赞信息表


表格准备完毕
代码实现
Controller层
/*** 实现文章点赞功能。* 通过请求映射 "/doLike",该方法处理用户对文章的点赞操作。* 使用@GlobalInterceptor注解,表明该方法受全局拦截器影响,会检查参数有效性及用户登录状态。** @param session 用户会话对象,用于获取会话中的用户信息。* @param articleId 需要点赞的文章ID,通过@VerifyParam注解确保其为非空,保证操作的有效性。* @return 返回操作成功的响应对象。*/@RequestMapping("/doLike")@GlobalInterceptor(checkParams = true, checkLogin = true)public ResponseVO likeArticle(HttpSession session, @VerifyParam(required = true) String articleId) {// 从会话中获取用户信息SessionWebUserDto sessionWebUserDto = getUserInfoFromSession(session);// 调用点赞服务,记录用户的点赞行为likeRecordService.doLike(articleId, sessionWebUserDto.getUserId(), sessionWebUserDto.getNickName(), OperRecordOpTypeEnum.ARTICLE_LIKE);// 返回操作成功的响应return getSuccessResponseVO(null);}
//枚举package com.easybbs.entity.enums;public enum OperRecordOpTypeEnum {ARTICLE_LIKE(0, "文章点赞"),COMMENT_LIKE(1, "评论点赞");private Integer type;private String desc;OperRecordOpTypeEnum(Integer type, String desc) {this.type = type;this.desc = desc;}public Integer getType() {return type;}public String getDesc() {return desc;}}
至于这里的参数校验和登录校验我就不作详细解释了,相信未来的你也一定可以看懂
Service接口层
//点赞void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum);
Service接口实现层
/*** 用户点赞操作。* 实现对文章或评论的点赞功能,并记录用户的点赞行为。* @param objectId 点赞对象的ID,可以是文章ID或评论ID。* @param userId 点赞用户的ID。* @param nickName 点赞用户的昵称。* @param opTypeEnum 点赞操作的类型,区分是文章点赞还是评论点赞。* @throws BusinessException 如果文章不存在,则抛出业务异常。*/@Override@Transactional(rollbackFor = Exception.class)public void doLike(String objectId, String userId, String nickName, OperRecordOpTypeEnum opTypeEnum) {// 创建用户消息对象,用于记录点赞行为。UserMessage userMessage = new UserMessage();userMessage.setCreateTime(new Date());// 根据点赞类型执行不同的操作。switch (opTypeEnum){case ARTICLE_LIKE:// 根据文章ID查询文章信息,如果文章不存在,则抛出异常。ForumArticle forumArticle = forumArticleMapper.selectByArticleId(objectId);if(forumArticle == null){throw new BusinessException("文章不存在");}// 执行文章点赞逻辑。articleLike(objectId,forumArticle,userId,opTypeEnum);// 设置用户消息的相关信息,如文章ID、文章标题等。userMessage.setArticleId(objectId);userMessage.setArticleTitle(forumArticle.getTitle());userMessage.setMessageType(MessageTypeEnum.ARTICLE_LIKE.getType());userMessage.setCommentId(Constants.ZERO);userMessage.setReceivedUserId(forumArticle.getUserId());break;case COMMENT_LIKE:// 评论点赞的逻辑实现。break;}// 设置用户消息的发送者信息。userMessage.setSendUserId(userId);userMessage.setSendNickName(nickName);userMessage.setStatus(MessageStatusEnum.NO_READ.getStatus());// 判断是否为给自己的点赞,若是,则不记录点赞消息。// 判断是否已经点赞if(!userId.equals(userMessage.getReceivedUserId())){// 根据文章ID、评论ID、发送者ID和消息类型查询是否已存在相同的点赞记录。UserMessage dbInfo = userMessageMapper.selectByArticleIdAndCommentIdAndSendUserIdAndMessageType(userMessage.getArticleId(),userMessage.getCommentId(),userMessage.getSendUserId(),userMessage.getMessageType());// 如果不存在相同的点赞记录,则插入新的点赞消息。if(dbInfo == null ){userMessageMapper.insert(userMessage);}}}/*** 用户对文章进行点赞或取消点赞操作。** @param objId 对象ID,即文章的唯一标识。* @param forumArticle 文章对象,用于获取文章的作者信息。* @param userId 用户ID,执行点赞操作的用户。* @param opTypeEnum 操作类型枚举,表示点赞或取消点赞。* @return 返回点赞记录,如果用户之前点赞过,则返回非空;否则返回空。*/public LikeRecord articleLike(String objId, ForumArticle forumArticle, String userId, OperRecordOpTypeEnum opTypeEnum) {// 根据对象ID、用户ID和操作类型查询点赞记录,判断用户是否已经点赞过。LikeRecord record = this.likeRecordMapper.selectByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());if (record != null) {// 如果用户之前点赞过,则取消点赞。this.likeRecordMapper.deleteByObjectIdAndUserIdAndOpType(objId, userId, opTypeEnum.getType());// 更新文章的点赞数,减少1。forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), -1, objId);} else {// 如果用户未点赞,则创建新的点赞记录。LikeRecord likeRecord = new LikeRecord();likeRecord.setObjectId(objId);likeRecord.setUserId(userId);likeRecord.setOpType(opTypeEnum.getType());likeRecord.setCreateTime(new Date());// 设置点赞记录的作者用户ID为文章的作者用户ID。likeRecord.setAuthorUserId(forumArticle.getUserId());// 插入新的点赞记录。this.likeRecordMapper.insert(likeRecord);// 更新文章的点赞数,增加1。forumArticleMapper.updateArticleCount(UpdateArticleCountTypeEnum.GOOD_COUNT.getType(), 1, objId);}// 返回点赞记录,无论是否新点赞或取消点赞。return record;}
Mapper层
<!-- 根据PrimaryKey获取对象--><select id="selectByArticleId" resultMap="base_result_map" >select <include refid="base_column_list" />,content,markdown_content from forum_article where article_id=#{articleId}</select><!-- 根据PrimaryKey获取对象--><select id="selectByArticleIdAndCommentIdAndSendUserIdAndMessageType" resultMap="base_result_map" >select <include refid="base_column_list" /> from user_message where article_id=#{articleId} and comment_id=#{commentId} and send_user_id=#{sendUserId} and message_type=#{messageType}</select><!-- 根据ObjectIdAndUserIdAndOpType删除--><delete id="deleteByObjectIdAndUserIdAndOpType">delete from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}</delete><!-- 根据PrimaryKey获取对象--><select id="selectByObjectIdAndUserIdAndOpType" resultMap="base_result_map" >select <include refid="base_column_list" /> from like_record where object_id=#{objectId} and user_id=#{userId} and op_type=#{opType}</select>
总结
当然上面只是一些代码的展示,但其实主要的是思路,那接下来我就说明一下我实现的思路
文章点赞功能,首先文章点赞传到Controller层的时候,肯定需要把文章id传送过去,在Controller接受到文章id之后,再从登录信息里面传递出来用户的id,用户的名称,是文章点赞还是评论点赞呢,传递过去之后,创建发送消息的对象,根据点赞类型进行分开,如果是文章点赞的话,首先根据用户id,文章id,点赞类型去查找点赞的记录表,如果说找到了的话,取消点赞,实际上也就是删除点赞信息,删除一条点赞信息表里面的语句,如果说没有点赞的话,创建一个点赞对象,点赞的人是这个用户,名称是这个用户,点赞的文章是文章id,点赞的类型是文章点赞,还需要额外设置点赞是给哪一个用户点赞,肯定是根据文章信息找到发送文章的人,然后插入新的点赞记录,更改文章的点赞数,如果说取消点赞也需要更改文章点赞类型,
点赞完成之后去继续完善用户发送信息表,比如说设置文章id,文章标题,文章点赞类型,接收人用户id是谁,发送人用户id是谁,发送人名字是谁,发送的是未读状态,
接下来首先需要判断不是自己给自己点赞,自己给自己点赞是肯定不会发送消息的,如果说根据文章id,评论的id发送者id,点赞类型查找如果说没有查找到的话,添加一条记录消息,总不能每次点赞完成之后都发送一次消息吧,发送的肯定是一次消息,大概逻辑就是这样
相关文章:
SpringBoot实现文章点赞功能
提示:今日是2024年的6月30日,未来的你看到这篇文章,希望你依旧快乐 文章目录 前言 首先在这里前缀部分我就不做要求了,比如说登录信息什么的 数据库表格 这里实现点赞功能,主要是围绕论坛项目完成的 user_info代表用户信息表 for…...
产品经理系列1—如何实现一个电商系统
具体笔记如下,主要按获客—找货—下单—售后四个部分进行模块拆解...
论文翻译 | (DSP)展示-搜索-预测:为知识密集型自然语言处理组合检索和语言模型
摘要 检索增强式上下文学习已经成为一种强大的方法,利用冻结语言模型 (LM) 和检索模型 (RM) 来解决知识密集型任务。现有工作将这些模型结合在简单的“检索-读取”流程中,其中 RM 检索到的段落被插入到 LM 提示中。 为了充分发挥冻结 LM 和 RM 的…...
1.(vue3.x+vite)实现卷帘效果
前端技术社区总目录(订阅之前请先查看该博客) 1:效果预览 2:代码编写 <template><div style="width...
HMI 的 UI 风格成就经典
HMI 的 UI 风格成就经典...
金融(基金)行业信创国产化特点及统一身份认证解决方案
金融业在政策支持及自主驱动下,金融信创取得快速发展。从2020年开始,三期试点已扩容至5000余家,进入全面推广阶段。而基金行业信创建设与银行、证券、保险这些试点行业相比,进展较为缓慢。 基金行业信创当前面临的问题 与多家基…...
透过 Go 语言探索 Linux 网络通信的本质
大家好,我是码农先森。 前言 各种编程语言百花齐放、百家争鸣,但是 “万变不离其中”。对于网络通信而言,每一种编程语言的实现方式都不一样;但其实,调用的底层逻辑都是一样的。linux 系统底层向上提供了统一的 Sock…...
【C语言】—— 文件操作(下)
【C语言】—— 文件操作(下) 前言:五、文件的顺序读写5.1、 顺序读写函数介绍5.2、 f p u t c fputc fputc 函数5.3、 f g e t c fgetc fgetc 函数5.4、 f p u t s fputs fputs 函数5.5、 f g e t s fgets fgets 函数5.6、 f p r i n t f…...
np.argsort
函数解释 np.argsort是NumPy库中的一个函数,用于对数组进行排序并返回排序后的索引。它不会直接对数组进行排序,而是返回一个数组,这个数组中的元素是原数组中元素按升序排序后的索引。 numpy.argsort(a, axis-1, kindNone, orderNone) 参…...
ORC与Parquet列式存储的区别
ORC与Parquet列式存储 1、ORC与Parquet列式存储2、ORC与Parquet的区别 列式存储(Columnar Storage)是一种优化的数据存储方式,与传统的行式存储(Row Storage)相比,列式存储在数据压缩、查询性能、I/O效率等…...
析构函数和拷贝构造函数
文章目录 析构函数1.析构函数的定义:2.析构函数的语法:3.析构函数的特性: 拷贝构造函数1.拷贝构造函数的定义:2.拷贝构造函数的语法3.拷贝构造函数的特性(1)拷贝构造函数是构造函数的一个重载形式**(这个其实也很好理解࿰…...
sql server启动、连接 与 navicat连接sql server
一、sql server 启动 1.搜索cmd->以管理员身份运行 2.输入以下命令 net start mssqlserver 3.服务器启动成功 二、sql server连接 1.打开ssms,输入,连接 2.右键,属性 3.连接,勾选允许远程连接到此服务器 三、navicat连接sq…...
数据库测试数据准备厂商 Snaplet 宣布停止运营
上周刚获知「数据库调优厂商 OtterTune 宣布停止运营」。而今天下班前,同事又突然刷到另一家海外数据库工具商 Snaplet 也停止运营了。Snaplet 主要帮助开发团队在数据库中生成仿真度高且合规的测试数据。我们在年初还撰文介绍过它「告别手搓!Postgres 一…...
【Java09】方法(下)
1. 形参个数可变的方法 Java允许方法指定数量不确定的形参。如果在定义方法是,在最后一个形参的类型后加...,则表明该形参可以接受多个参数值。多个参数值作为数组传入: public class Varargs {public static void test(int a, String... b…...
d88888888
分析:v9999999999 vn输出n个n 先算出n的位数p 所以答案是nn*10的p次方n*10的2p次方.....n*10的(n-1)p次方 化简n*(10的0次方10的p次方10的2p次方.....10的(n-1)p次方) 后面为等比数列求和 …...
【MySQL备份】mysqldump基础篇
目录 1.简介 2.基本用途 3.命令格式 3.1常用选项 3.2常用命令 4.备份脚本 5.定时执行备份脚本 1.简介 mysqldump 是 MySQL 数据库管理系统的命令行实用程序,用于创建数据库的逻辑备份。它能够导出数据库的结构(如表结构、视图、触发器等…...
C# Halcon目标检测算法
在Halcon中进行目标检测可以使用传统的计算机视觉方法,也可以使用深度学习的方法。Halcon提供了丰富的函数库来处理这些任务,而在C#中使用Halcon,你需要通过Halcon .NET接口。 以下是使用Halcon进行目标检测的一般步骤,这里我将给…...
7.4总结
今天写了几道题目 最近,一年级学生马克西姆学习了科拉兹猜想,但他在讲课时没有太注意,所以他认为猜想中提到了以下过程: 有一个变量 $$$x$$$ 和一个常数 $$$y$$$ 。下面的操作要执行 $$$k$$$ 次: - 将 $$$x$$$ 增加…...
知识图谱查询语言的表示
文章目录 SPARQL知识图谱查询基本构成常见的SPARQL查询算子语义Markup表示语言SPARQL知识图谱查询基本构成 RDF 支持类似数据库的查询语言,叫作SPARQL,它提供了查询RDF 数据的标准语法、处理SPARQL查询的规则以及结果返回形式。 变量,RDF中的资源,以“?”或者“$”指示;…...
重生之我要学后端100--计算机网络部分概念(持续更新)
TCP/IP、DNS、负载均衡器等等 前言一、TCP/IP(传输控制协议/互联网协议)二、DNS(域名系统)三、负载均衡器其他网络概念 前言 了解网络基础知识对于后端开发者至关重要,因为这些知识有助于理解应用程序是如何在更广阔的…...
用OpenMV和STM32F765VI做个追球小车:从硬件接线到PID调参的保姆级避坑指南
从零打造智能追球小车:OpenMV与STM32F765VI实战全解析 1. 项目构思与硬件选型 第一次尝试用视觉识别做智能小车时,我对着满桌子的开发板和传感器发愁——到底哪些组合才能既省钱又高效?经过三个版本的迭代,这套基于STM32F765VI和O…...
自动化测试框架选型:Selenium vs Cypress深度对比
在快速迭代的软件开发周期中,自动化测试框架的选型直接影响产品质量与交付效率。Selenium与Cypress作为当前主流工具,分别代表了传统与现代化的技术路线。本文将从架构设计、核心特性、适用场景及未来趋势等维度,为测试从业者提供深度对比分析…...
Qwen2.5-72B-Instruct-GPTQ-Int4实战案例:新能源电池BMS日志分析与故障模式推演
Qwen2.5-72B-Instruct-GPTQ-Int4实战案例:新能源电池BMS日志分析与故障模式推演 1. 项目背景与模型介绍 新能源电池管理系统(BMS)是电动汽车和储能系统的核心组件,每天产生大量运行日志数据。传统分析方法依赖人工经验,效率低下且难以发现潜…...
服装设计降本增效:Nano-Banana软萌拆拆屋缩短打样周期实证
服装设计降本增效:Nano-Banana软萌拆拆屋缩短打样周期实证 在服装设计行业,从创意草图到实物样衣,打样环节往往是成本最高、耗时最长的“拦路虎”。设计师需要反复与版师、样衣工沟通,绘制复杂的工艺图,一个款式来回修…...
OpenClaw 的模型服务是否支持基于策略的流量控制?
关于OpenClaw模型服务是否支持基于策略的流量控制,这个问题其实触及了现代AI服务部署中一个相当核心的环节。直接说结论的话,答案是肯定的,但更值得探讨的是它具体如何实现,以及这种支持在实际场景中意味着什么。 在技术架构层面&…...
如何让AI创作速度提升3倍?智能缓存技术TeaCache的完整指南
如何让AI创作速度提升3倍?智能缓存技术TeaCache的完整指南 【免费下载链接】ComfyUI-TeaCache 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-TeaCache 你是否曾为AI图像和视频生成的速度而烦恼?看着进度条缓慢移动,等待数分…...
互联网大厂Java面试实战:严肃面试官与搞笑程序员谢飞机的三轮问答
互联网大厂Java面试实战:严肃面试官与搞笑程序员谢飞机的三轮问答 在互联网大厂Java岗位面试中,面试官不仅考察应聘者的技术深度,更关注其理解业务场景的能力和解决问题的方法。本文通过一场幽默而真实的模拟面试,呈现核心Java与周…...
保姆级教程:Nanbeige 4.1-3B Streamlit WebUI的MySQL数据持久化配置
保姆级教程:Nanbeige 4.1-3B Streamlit WebUI的MySQL数据持久化配置 你是不是也遇到过这样的烦恼?用Streamlit给Nanbeige大模型搭了个漂亮的对话界面,每次聊得正开心,结果一刷新页面或者重启应用,之前的对话记录全没了…...
软件开发中的架构:概念、价值与常见模式
在软件工程实践中,“架构”是一个高频出现但又常被误解的术语。很多人将其等同于技术选型或框架选择,但实际上,软件架构远不止于此。它关乎系统的整体结构、组件之间的关系以及指导系统演进的核心原则。本文将系统性地解释什么是软件架构、为…...
LabelImg图像标注工具:3分钟掌握高效目标检测数据标注技巧
LabelImg图像标注工具:3分钟掌握高效目标检测数据标注技巧 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check ou…...
