基于springboot的评论,点赞模块

    科技2025-07-18  4

    关注作者及转自https://blog.csdn.net/qq_43308337/article/details/104753640

    项目地址:点击访问 欢迎各位fork,star

    1. 分析阶段

    1.先从前端入手,看看前端需要哪些数据(这里以csdn博客评论为列),以博客为例,一篇博客下面可能会有多条评论。每条评论其实分为两种,一种是直接对博客的评论,称之为父评论;另一种是对已有评论的评论(博主回复),称为子评论。点赞就比较好区分了,无论是父评论还是子评论或者博客评论,点赞只要关联被评论对象的唯一标识和点赞用户的id就可以了。一篇博客可以有多条评论,一条父评论,可以有多条子评论。所以博客与评论的关系为一对多,父评论与子评论的关系也是一对多,一个点赞对应一个点赞对象,所以点赞与点赞的对象为一对一,由此则可以设置数据库表。

    2.设计阶段

    由此可以得出,评论分为两种:一种为父评论,另一种为子评论。则: 一条父评论至少拥有的属性为:评论的唯一标识,评论对象的id,评论者的id,评论者名字,评论者的头像,评论的内容,评论的点赞数,评论发布的时间

    一条子评论至少拥有的属性为:父评论的唯一标识,评论者的id,评论者名字,评论者的头像,,被评论者的id,被评论者名字,被评论者的头像,评论的内容,评论的点赞数,评论发布的时间

    一条评论的点赞至少拥有的属性为:被评论对象的唯一标识,用户的唯一标识,点赞状态 由此就可以设计数据库表了。父评论表(comments_root):

    id主键type评论的类型,评论博客,评论下载资源等owner_id评论对象的idfrom_id评论者的idfrom_name评论者的名字from_avatar评论者的头像链接like_num评论的点赞数content评论的内容comment_id评论的唯一标识create_time评论的发布时间

    子评论表(comments_reply):

    id用来关联父评论的主键idcomment_id子评论的唯一标识from_id评论者的idfrom_name评论者的名字from_avatar评论者的头像链接to_id被评论者的idto_name被评论者的名字to_avatar被评论者的头像链接like_num评论的点赞数content评论的内容create_time评论的发布时间

    点赞表(liked)

    id主键obj_id对应对象的id,可以是文章id或者评论id等user_id点赞者的idlike_status点赞的状态,1标识已赞,0标识取消赞

    3.创建工程

    (1)创建springboot项目,然后在项目根目录下的 pom.xml 文件中添加如下依赖:

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.tl666</groupId> <artifactId>comments</artifactId> <version>0.0.1-SNAPSHOT</version> <name>comments</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.18</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>

    (2)编辑配置文件application.yml或application.properties中添加配置,博主用的是yml格式的配置文件,它格式比较清晰,application.yml

    spring: datasource: driver-class-name: com.mysql.jdbc.Driver username: root password: 123456 url: jdbc:mysql://127.0.0.1/comments?characterEncoding=utf-8&useSSL=false mybatis: configuration: mapUnderscoreToCamelCase: true #开启mabatis的驼峰命名法

    (3)然后在springboot中写好对应的实体类即可 (4)然后写数据持久化层CommentsMapper.java

    package com.tl666.comments.mapper; import com.tl666.comments.pojo.CommentsRoot; import com.tl666.comments.pojo.CommentsReply; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface CommentsMapper { /** * 获取该文章或资源下的所有评论 * @param ownerId 文章或资源id * @return */ // @Select("select * from comments_info where owner_id = #{ownerId}") List<CommentsRoot> findByOwnerId(String ownerId); /** * 添加子评论或回复评论 * @param commentsReply * @return */ @Insert("insert into comments_reply (id,comment_id,from_id,from_name,from_avatar,to_id,to_name,to_avatar,like_num,content,create_time) " + "values(#{id},#{commentId},#{fromId},#{fromName},#{fromAvatar},#{toId},#{toName},#{toAvatar},#{likeNum},#{content},#{createTime})") boolean addSonComments(CommentsReply commentsReply); /** * 添加父评论 * @param commentsRoot * @return */ // @Insert("insert into comments_root (id,comment_id,owner_id,type,from_id,from_name,from_avatar,like_num,content,create_time) " + // "values(#{id},#{commentId},#{ownerId},#{type},#{fromId},#{fromName},#{fromAvatar},#{likeNum},#{content},#{createTime})") boolean addRootComments(CommentsRoot commentsRoot); }

    对应的mybatis的xml文件CommentsMapper .xml如下

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--一对多的映射 --> <mapper namespace="com.tl666.comments.mapper.CommentsMapper"> <select id="findByOwnerId" resultMap="Comnents"> select * from comments_root where owner_id = #{ownerId} </select> <resultMap type="com.tl666.comments.pojo.CommentsRoot" id="Comnents"> <result property="id" column="id" /> <collection property="listCommentsReply" javaType="ArrayList" ofType="com.tl666.comments.pojo.CommentsReply" column="id" select="getSonComments"></collection> </resultMap> <select id="getSonComments" resultType="com.tl666.comments.pojo.CommentsReply"> select * from comments_reply where id = #{id} </select> <insert id="addRootComments" parameterType="com.tl666.comments.pojo.CommentsRoot" keyProperty="id"> <selectKey keyProperty='id' resultType='int' order='AFTER' > select LAST_INSERT_ID(); </selectKey> insert into comments_root (id,comment_id,owner_id,type,from_id,from_name,from_avatar,like_num,content,create_time) values(#{id},#{commentId},#{ownerId},#{type},#{fromId},#{fromName},#{fromAvatar},#{likeNum},#{content},#{createTime}) </insert> </mapper>

    (5)控制层的核心代码如下

    /** * 添加父评论 直接对标文章,资源等下面的评论 * @param commentsRoot * @return */ @PostMapping("addRootComments") public ResultDT addRootComments(CommentsRoot commentsRoot) { log.info("1" + commentsRoot.toString()); if (commentsRoot.getContent().length() != 0) { commentsRoot.setCommentId(UUID.randomUUID().toString().replaceAll("-", ""));//设置评论唯一标识 commentsRoot.setCreateTime(new Date());//设置添加评论时间 log.info("2" + commentsRoot); boolean b = commentService.addRootCommentsService(commentsRoot); //调用service方法来完成评论的存储 log.info("3" + commentsRoot.toString()); if (b) { return ResultDTUtils.success(commentsRoot); } } //评论内容为空 返回错误信息 return ResultDTUtils.error(ResultDTUtils.COMMENT_ERROR, "addError"); } /** * 添加子评论,对应父评论 * @param commentsReply * @return */ @PostMapping("addSonComments") public ResultDT addSonComments(CommentsReply commentsReply) { log.info("1" + commentsReply.toString()); if (commentsReply.getContent().length() != 0) { commentsReply.setCommentId(UUID.randomUUID().toString().replaceAll("-", ""));//设置评论唯一标识 commentsReply.setCreateTime(new Date()); log.info("2" + commentsReply); boolean b = commentService.addSonCommentsService(commentsReply); log.info("3" + commentsReply.toString()); if (b) { return ResultDTUtils.success(commentsReply); } } return ResultDTUtils.error(ResultDTUtils.COMMENT_ERROR, "addError"); } /** * 根据资源ID来回去该资源的所有评论 * @param request * @return */ @GetMapping("getListByOwnerId") public ResultDT getListByOwnerId(HttpServletRequest request) { String ownerId = request.getParameter("owner_id"); log.info(ownerId); List<CommentsRoot> byOwnerIdService = commentService.findByOwnerIdService(ownerId); log.info(byOwnerIdService.toString()); return ResultDTUtils.success(byOwnerIdService); }

    (6)评论效果如下图所示: 点击回复输入框会出现回复的对象的名字 从后端获取的评论数据 项目地址:点击访问

    Processed: 0.010, SQL: 8