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

springboot中使用mongodb完成评论功能

pom文件中引入

<!-- mongodb -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

yml中配置连接

data:mongodb:uri: mongodb://admin:123456@127.0.0.1:27017/test?authSource=admin&authMechanism=SCRAM-SHA-1

评论表字段如下(根据自己的需求设计)

public class Comment {@Id@ApiModelProperty(value = "评论id***********数据类型:string")private String id;/*** 父级评论id*/@ApiModelProperty(value = "父级评论id***********数据类型:int")private String pid;/*** 用户id*/@ApiModelProperty(value = "用户id***********数据类型:int")private Integer customerId;/*** 用户姓名*/@ApiModelProperty(value = "用户姓名***********数据类型:string")private String customerName;/*** 用户头像*/@ApiModelProperty(value = "用户头像***********数据类型:string")private String customerAvatar;/*** 是否是会员:1:是;2:否*/@ApiModelProperty(value = "是否是会员:1:是;2:否***********数据类型:int")private Integer customerIsVip;/*** 评论内容*/@ApiModelProperty(value = "评论内容***********数据类型:string")private String content;/*** 评论图片*/@ApiModelProperty(value = "评论图片***********数据类型:string")private String image;/*** 业务类型 */@ApiModelProperty(value = "业务类型***********数据类型:int")private Integer busType;/*** 业务id*/@ApiModelProperty(value = "业务id***********数据类型:long")private Long busId;/*** 审核状态 1:待审核;2:审核通过;3:审核失败*/@ApiModelProperty(value = "审核状态 1:待审核;2:审核通过;3:审核失败***********数据类型:int")private Integer isShow;/*** 是否置顶 1:是;2:否*/@ApiModelProperty(value = "是否置顶 1:是;2:否***********数据类型:int")private Integer isTop;/*** 是否是作者 1:是;2:否*/@ApiModelProperty(value = "是否是作者 1:是;2:否***********数据类型:int")private Integer isAuthor;/*** 是否为精选评论 1:是;2:否*/@ApiModelProperty(value = "是否为精选评论 1:是;2:否***********数据类型:int")private Integer isFeatured;/*** 是否为首评 1:是;2:否*/@ApiModelProperty(value = "是否为首评 1:是;2:否***********数据类型:int")private Integer isFirst;/*** 被回复评论id*/@ApiModelProperty(value = "被回复评论id***********数据类型:int")private String replyId;/*** 被回复用户id*/@ApiModelProperty(value = "被回复用户id***********数据类型:int")private Integer replyCustomerId;/*** 是否是会员:1:是;2:否*/@ApiModelProperty(value = "是否是会员:1:是;2:否***********数据类型:int")private Integer replyCustomerIsVip;/*** 被回复用户姓名*/@ApiModelProperty(value = "被回复用户姓名***********数据类型:string")private String replyCustomerName;/*** 被回复用户头像*/@ApiModelProperty(value = "被回复用户头像***********数据类型:string")private String replyCustomerAvatar;/*** 点赞数量*/@ApiModelProperty(value = "点赞数量***********数据类型:int")private Integer likeCount;/*** 点赞状态 1:已赞;2:未赞*/@ApiModelProperty(value = "点赞状态 1:已赞;2:未赞***********数据类型:int")private Integer thumbUpStatus;/*** 是否是朋友 0:是;1:否*/@ApiModelProperty(value = "点赞状态 1:已赞;2:未赞***********数据类型:int")private Integer isFriend;/*** 发表时间*/@ApiModelProperty(value = "发表时间***********数据类型:date")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date createTime;/*** 是否是首评 1:是;2:否*/@ApiModelProperty(value = "是否是首评 1:是;2:否***********数据类型:int")public Integer getIsFirst() {return isFirst;}/*** 是否是回复1级  1:是;2否*/@ApiModelProperty(value = "是否是回复1级  1:是;2否***********数据类型:int")public Integer isReplyOne;/*** 修改时间*/@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private Date updateTime;/*** 子评论*/@ApiModelProperty(value = "子评论***********数据类型:obj")private Page<AiComment> childrens;

创建CommentRespository并且继MongoRepository<Comment,String>

package com.mongo.respository;import com.mongo.domain.Comment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.MongoRepository;import java.util.List;public interface CommentRespository extends MongoRepository<Comment,String> {/*** 通过条件查询分页* @date 2024/10/12 18:05* @param busType 业务类型* @param busId 业务id* @param isShow 是否显示* @param pid 父id* @param pageable 分页* @return */Page<Comment> findByBusTypeAndBusIdAndIsShowAndPid(Integer busType, Long busId, Integer isShow, String pid, Pageable pageable);/*** 通过评论id查询* @date 2024/11/27 11:35* @param id 评论id* @param list 是否显示* @param pageable  分页* @return */Page<Comment> findByIdAndIsShowIn(String id, List<Integer> list, Pageable pageable);/*** 通过业务类型和业务id查询是否存在评论* @date 2024/11/18 10:44* @param busType 业务类型 * @param busId 业务id  * @return*/List<Comment> findAiCommentByBusTypeAndAndBusId(Integer busType,Long busId);/*** 通过条件查询分页(如果有敏感的词自己可以查看)* @date 2024/11/21 18:23* @param busType 业务类型* @param busId 业务id* @param isShow 是否显示* @param pid 父id* @param busType2 业务类型* @param busId2 业务id* @param pid2 父id* @param customerId 用户id* @param list 审核状态* @param pageable 分页* @return*/Page<Comment> findByBusTypeAndBusIdAndIsShowAndPidOrBusTypeAndBusIdAndPidAndCustomerIdAndIsShowIn(Integer busType,Long busId,Integer isShow,String pid,Integer busType2,Long busId2,String pid2,Integer customerId,List<Integer> list,Pageable pageable);
}

 此MongoRepository的好处是对于一些比较简单的查询可以直接按字段组装来查询

比如findByIdAndIsShowIn  就是通过业务id和展示的状态来查询 直接见明识意

还有一种查询方式针对比较麻烦的sql语句

在respository中定义

package com.mongo.respository;import com.mongo.domain.AiComment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;import java.util.Date;
import java.util.List;public interface CommentRespository extends MongoRepository<Comment,String> {/*** 条件查询分页* @date 2024/11/10 11:42* @param customerId 评论人id* @param isShow 审核状态* @param isFeature 是否是精选* @param startDate 开始日期* @param endDate 结束日期* @param pageable 分页* @return*/List<Comment> findByParams(Integer customerId, Integer isShow, Integer isFeature, Date startDate, Date endDate, Pageable pageable);/*** 条件查询总数* @date 2024/11/10 11:42* @param customerId 评论人id* @param isShow 审核状态* @param isFeature 是否是精选* @param startDate 开始日期* @param endDate 结束日期* @return java.lang.Long*/Long countParams(Integer customerId, Integer isShow, Integer isFeature, Date startDate, Date endDate);
}

实现类继承此类

package com.mongo.respository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import com.mongo.domain.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.stereotype.Repository;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;@Repository
public class CommentRespositoryImpl implements CommentRespository{@Autowiredprivate MongoTemplate mongoTemplate;/*** 条件查询分页* @date 2024/11/10 11:42* @param customerId 评论人id* @param isShow 审核状态* @param isFeature 是否是精选* @param startDate 开始日期* @param endDate 结束日期* @param pageable 分页* @return*/@Overridepublic List<Comment> findByParams(Integer customerId, Integer isShow, Integer isFeature, Date startDate, Date endDate, Pageable pageable) {Criteria criteria = new Criteria();Query query = new Query();if (null != customerId) {criteria.and("customerId").is(customerId);}if (null != isShow) {criteria.and("isShow").is(isShow);}if (null != isFeature) {criteria.and("isFeatured").is(isFeature);}if (null != startDate && null != endDate) {criteria.and("createTime").gte(startDate).lte(endDate);} else if (startDate!= null) {criteria.and("createTime").gte(startDate);} else if (endDate!= null) {criteria.and("createTime").lte(endDate);}query.addCriteria(criteria);return mongoTemplate.find(query.with(pageable), Comment.class);}/*** 条件查询总数* @date 2024/11/10 11:42* @param customerId 评论人id* @param isShow 审核状态* @param isFeature 是否是精选* @param startDate 开始日期* @param endDate 结束日期* @return java.lang.Long*/@Overridepublic Long countParams(Integer customerId, Integer isShow, Integer isFeature, Date startDate, Date endDate) {List<Criteria> criteriaList = new ArrayList<>();if (null != customerId) {criteriaList.add(Criteria.where("customerId").is(customerId));}if (null != isShow) {criteriaList.add(Criteria.where("isShow").is(isShow));}if (null != isFeature) {criteriaList.add(Criteria.where("isFeatured").is(isFeature));}if (null != startDate && null != endDate) {criteriaList.add(Criteria.where("createTime").gte(startDate).lte(endDate));} else if (startDate!= null) {criteriaList.add(Criteria.where("createTime").gte(startDate));} else if (endDate!= null) {criteriaList.add(Criteria.where("createTime").lte(endDate));}if (criteriaList.isEmpty()) {List<Comment> comments = mongoTemplate.findAll(Comment.class);if (comments.isEmpty()) {return 0L;} else {return (long) comments.size();}} else {Query query = Query.query(Criteria.where("").andOperator(criteriaList.toArray(new Criteria[0])));List<AiComment> posts = mongoTemplate.find(query, Comment.class);if (posts.isEmpty()) {return 0L;} else {return (long) posts.size();}}}}

通过Criteria和Query结合来查询

最后评论效果

评论字段说明

isReplyOne 如果是1的情况下回复一级就不显示谁回复谁

如果是一级以下的子评论isReplyOne是2就显示 张三回复李四

查询sql说明

PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize, Sort.by(Sort.Order.asc("isTop"), Sort.Order.desc("createTime")));
Page<Comment> page;
if (0 == customerId) {page = aiCommentRespository.findByBusTypeAndBusIdAndIsShowAndPid(busType, busId, IsShowEnum.YES.getKey(), "0", pageRequest);
} else {page = aiCommentRespository.findByBusTypeAndBusIdAndIsShowAndPidOrBusTypeAndBusIdAndPidAndCustomerIdAndIsShowIn(busType, busId, IsShowEnum.CHECK_SUCCESS.getKey(), "0", busType, busId, "0", customerId, Arrays.asList(0, 1), pageRequest);
}

这里判断customerId为0是用户登陆与不登陆的情况下的操作

Arrays.asList(0, 1) 解释:因为评论可能涉及敏感信息,当用户自己评论了带有敏感的系统自动检测为敏感状态变为0(待审核状态),自己可以看到而别的用户不可以看到,所以isShow的查询条件为0,1。1为审核通过状态

findByBusTypeAndBusIdAndIsShowAndPidOrBusTypeAndBusIdAndPidAndCustomerIdAndIsShowIn

这条sql的解释:这是一条or语句

BusTypeAndBusIdAndIsShowAndPid 这是为了查询审核通过的评论

而or后面的语句是为了当本人评论了敏感的信息后可以让本人看到自己的评论而别人不可以看到

BusTypeAndBusIdAndPidAndCustomerIdAndIsShowIn

查询子评论 只需要要循环上面的评论 把pid换成主评论id即可

http://www.lryc.cn/news/494125.html

相关文章:

  • Dubbo的RPC泛化调用
  • 【k8s深入理解之 Scheme】全面理解 Scheme 的注册机制、内外部版本、自动转换函数、默认填充函数、Options等机制
  • 接口性能优化宝典:解决性能瓶颈的策略与实践
  • 雨晨 Windows Server 2025 数据中心 极简 26311.5000
  • 关于IDE的相关知识之三【插件安装、配置及推荐的意义】
  • JSP+Servlet实现列表分页功能
  • 操作系统存储器相关习题
  • QUICK 调试camera-xml解析
  • 【linux】shell脚本编写基础
  • STM32 外设简介
  • Django-Vue3-Admin - 现代化的前后端分离权限管理系统
  • Cesium K-means自动聚合点的原理
  • Vue 项目中如何解决组件之间的循环依赖
  • 交通流量预测:基于交通流量数据建立模型
  • Hot100 - 搜索二维矩阵II
  • uart_pl011.c驱动API的zephyr测试
  • RPA:电商订单处理自动化
  • 小程序 - 个人简历
  • MySQL自启动失败(MySQL不能开机自启)解决方案_MySQL开机自启疑难杂症解决,适用Win11/Win10
  • 储存水..
  • Cmake 常用操作总结
  • Kylin Server V10 下 RocketMQ 主备自动切换模式部署
  • DevOps工程技术价值流:GitLab源码管理与提交流水线实践
  • Vue 3 中实现页面特定功能控制
  • VLC 播放的音视频数据处理流水线搭建
  • 何时在 SQL 中使用 CHAR、VARCHAR 和 VARCHAR(MAX)
  • 学习笔记043——HashMap源码学习1
  • 单点登录原理
  • 【随笔】AI大模型对软件开发的影响
  • JAVA中接口类和抽象类的区别