瑞_MongoDB_案例-文章评论

瑞&3l

🙊 前言:本文章为瑞_系列专栏之《MongoDB》的案例-文章评论篇。由于博主是从B站黑马程序员的《MongoDB》学习其相关知识,所以本系列专栏主要是针对该课程进行笔记总结和拓展,文中的部分原理及图解等也是来源于黑马提供的资料,特此注明。本文仅供大家交流、学习及研究使用,禁止用于商业用途,违者必究!

系列整合篇:《瑞_MongoDB(笔记超详细,有这一篇就够了)》




5 文章评论

本文是使用 SpringDataMongoDB 简单模拟某头条的文章评论业务的实现过程

案例环境
  • CentOS 7
  • Java 1.8
  • MongoDB Linux 4.0.10

5.1 需求分析

  需要实现以下功能

  1️⃣ 基本增删改查API

  2️⃣ 根据文章 id 查询评论,分页效果

  3️⃣ 评论点赞

5.2 表结构分析

  • 数据库:articledb
  • 集合(数据表):comment,存放专栏文章评论
字段名称字段含义字段类型备注
_idIDObjectId或StringMongo的主键的字段
articleid文章IDString/
content评论内容String/
userid评论人IDString/
nickname评论人昵称String/
createdatetime评论的日期时间Date/
likenum点赞数Int32/
replynum回复数Int32/
state状态String0:不可见;1:可见;
parentid上级IDString如果为0表示文章的顶级评论

瑞:_id比较特殊,是 MongoDB 里面的主键,是自己生成的。其它字段都是需要演示的业务字段。

5.3 技术选型

5.3.1 mongodb-driver

  mongodb-driver 是 MongoDB 官方推出的 java 连接 MongoDB 的驱动包,相当于JDBC 驱动。

  官方驱动说明和下载:http://mongodb.github.io/mongo-java-driver/

  官方驱动示例文档:http://mongodb.github.io/mongo-java-driver/3.8/driver/getting-started/quick-start/

5.3.2 SpringDataMongoDB

  SpringData 家族成员之一,用于操作 MongoDB 的持久层框架,封装了底层的 mongodb-driver。

  官网主页: https://projects.spring.io/spring-data-mongodb/

5.4 项目搭建

5.4.1 MongoDB 数据准备

  MongoDB 中通过隐式创建文档的方式创建数据库articledb和集合comment并批量插入测试数据的命令如下⬇️

# 隐式创建数据库 articledb
use articledb

# 创建集合comment并插入数据
db.comment.insertMany([{"_id":"1","articleid":"100001","content":"我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我他。","userid":"1002","nickname":"相忘于江湖","createdatetime":new Date("2019-08-05T22:08:15.522Z"),"likenum":NumberInt(1000),"state":"1"},{"_id":"2","articleid":"100001","content":"我夏天空腹喝凉开水,冬天喝温开水","userid":"1005","nickname":"伊人憔悴","createdatetime":new Date("2019-08-05T23:58:51.485Z"),"likenum":NumberInt(888),"state":"1"},{"_id":"3","articleid":"100001","content":"我一直喝凉开水,冬天夏天都喝。","userid":"1004","nickname":"杰克船长","createdatetime":new Date("2019-08-06T01:05:06.321Z"),"likenum":NumberInt(666),"state":"1"},{"_id":"4","articleid":"100001","content":"专家说不能空腹吃饭,影响健康。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T08:18:35.288Z"),"likenum":NumberInt(2000),"state":"1"},{"_id":"5","articleid":"100001","content":"研究表明,刚烧开的水千万不能喝,因为烫嘴。","userid":"1003","nickname":"凯撒","createdatetime":new Date("2019-08-06T11:01:02.521Z"),"likenum":NumberInt(3000),"state":"1"}]);
5.4.2 Java项目搭建

  文章微服务模块搭建步骤如下

  1️⃣ 使用 IDEA 创建一个 Maven 项目

在这里插入图片描述

  2️⃣ 项目工程名称为 article

在这里插入图片描述

  3️⃣ 在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 http://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.7.12</version>
        <relativePath/>
    </parent>

    <groupId>com.ray.study.mongodb-study</groupId>
    <artifactId>article</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>
</project>

  4️⃣ 在resource路径下创建application.yml,其中地址要记得替换为你 MongoDB 服务的地址

spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
      host: 192.168.133.131
      # 数据库
      database: articledb
      # 默认端口是27017
      port: 27017
      # 方式二:使用uri连接
#      uri: mongodb://192.168.133.131:27017/articledb

在这里插入图片描述

  5️⃣ 创建启动类com.ray.study.mongodb.article.ArticleApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@SpringBootApplication
public class ArticleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ArticleApplication.class, args);
    }
}

在这里插入图片描述

  6️⃣ 启动项目,看是否能正常启动,控制台如果没有错误则配置 MongoDB 成功

在这里插入图片描述

5.5 文章评论实体类的编写

  1️⃣ 创建包com.ray.study.mongodb.article.po

在这里插入图片描述

  2️⃣ 在该包下创建实体类Comment

package com.ray.study.mongodb.article.po;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 文章评论实体类
 *
 * <p>把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。</p>
 * <p>@Document(collection="mongodb 对应 collection 名")</p>
 * <p>若未加 @Document ,该 bean save 到 mongo 的 comment collection</p>
 * <p>若添加 @Document ,则 save 到 comment collection</p>
 * <p></p>
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@Document(collection="comment") // 可以省略,如果省略,则默认使用类名小写映射集合
@CompoundIndex( def = "{'userid': 1, 'nickname': -1}") // 复合索引
public class Comment implements Serializable {
    // 主键标识,该属性的值会自动对应mongodb的主键字段"_id",如果该属性名就叫“id”,则该注解可以省略,否则必须写
    @Id
    private String id; // 主键

    // 该属性对应mongodb的字段的名字,如果一致,则无需该注解
    @Field("content")
    private String content;// 吐槽内容

    private Date publishtime;// 发布日期

    // 添加了一个单字段的索引
    @Indexed
    private String userid; // 发布人ID

    private String nickname; // 昵称

    private LocalDateTime createdatetime; // 评论的日期时间

    private Integer likenum; // 点赞数

    private Integer replynum; // 回复数

    private String state; // 状态

    private String parentid; // 上级ID

    private String articleid; // 文章ID

    //getter and setter.....

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getPublishtime() {
        return publishtime;
    }

    public void setPublishtime(Date publishtime) {
        this.publishtime = publishtime;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public LocalDateTime getCreatedatetime() {
        return createdatetime;
    }

    public void setCreatedatetime(LocalDateTime createdatetime) {
        this.createdatetime = createdatetime;
    }

    public Integer getLikenum() {
        return likenum;
    }

    public void setLikenum(Integer likenum) {
        this.likenum = likenum;
    }

    public Integer getReplynum() {
        return replynum;
    }

    public void setReplynum(Integer replynum) {
        this.replynum = replynum;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getParentid() {
        return parentid;
    }

    public void setParentid(String parentid) {
        this.parentid = parentid;
    }

    public String getArticleid() {
        return articleid;
    }

    public void setArticleid(String articleid) {
        this.articleid = articleid;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id='" + id + '\'' +
                ", content='" + content + '\'' +
                ", publishtime=" + publishtime +
                ", userid='" + userid + '\'' +
                ", nickname='" + nickname + '\'' +
                ", createdatetime=" + createdatetime +
                ", likenum=" + likenum +
                ", replynum=" + replynum +
                ", state='" + state + '\'' +
                ", parentid='" + parentid + '\'' +
                ", articleid='" + articleid + '\'' +
                '}';
    }
}

  【说明】
  索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过 MongoDB 的命令来添加,也可以在 Java 的实体类中通过注解添加

@Indexed注解
  • 单字段索引注解@Indexed

  路径org.springframework.data.mongodb.core.index.Indexed.class

  作用:声明该字段需要索引,建索引可以大大的提高查询效率

  MongoDB 命令参考db.collection_name.createIndex(keys, options)

  示例

db.comment.createIndex({"userid":1})
@CompoundIndex注解
  • 复合索引注解@CompoundIndex

  路径org.springframework.data.mongodb.core.index.CompoundIndex.class

  作用:复合索引的声明,建复合索引可以有效地提高多字段的查询效率。

  MongoDB 命令参考db.collection_name.createIndex(keys, options)

  示例

db.comment.createIndex({"userid":1,"nickname":-1})

5.6 文章评论的基本增删改查

  1️⃣ 创建包com.ray.study.mongodb.article.dao

  2️⃣ 创建包com.ray.study.mongodb.article.service

在这里插入图片描述
  3️⃣ 在dao包下创建接口CommentRepository,要继承org.springframework.data.mongodb.repository.MongoRepository,泛型为实体类和主键类型

import com.ray.study.mongodb.article.po.Comment;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * 评论的dao接口
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
public interface CommentRepository extends MongoRepository<Comment,String> {

}

  4️⃣ 在service包下创建CommentService


import com.ray.study.mongodb.article.dao.CommentRepository;
import com.ray.study.mongodb.article.po.Comment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 评论的业务层
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@Service
public class CommentService {
    // 注入dao
    @Resource
    private CommentRepository commentRepository;

    /**
     * 保存一个评论
     */
    public void saveComment(Comment comment) {
        // 如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键
        // 设置一些默认初始值。。。
        // 调用dao
        commentRepository.save(comment);
    }


    /**
     * 更新评论
     */
    public void updateComment(Comment comment) {
        // 调用dao
        commentRepository.save(comment);
    }

    /**
     * 根据id删除评论
     */
    public void deleteCommentById(String id) {
        // 调用dao
        commentRepository.deleteById(id);
    }

    /**
     * 查询所有评论
     */
    public List<Comment> findCommentList() {
        // 调用dao
        return commentRepository.findAll();
    }

    /**
     * 根据id查询评论
     */
    public Comment findCommentById(String id) {
        // 调用dao
        return commentRepository.findById(id).get();
    }

}

  5️⃣ 在test包下创建com.ray.study.mongodb.article.service包,并创建CommentServiceTest测试类

在这里插入图片描述

import com.ray.study.mongodb.article.ArticleApplication;
import com.ray.study.mongodb.article.po.Comment;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;


@SpringBootTest(classes = ArticleApplication.class)
public class CommentServiceTest {
    // 注入Service
    @Resource
    private CommentService commentService;

    /**
     * 查询所有数据
     */
    @Test
    public void testFindAll(){
        List<Comment> list = commentService.findCommentList();
        System.out.println(list);
    }

    /**
     * 测试根据id查询
     */
    @Test
    public void testFindCommentById(){
        Comment comment = commentService.findCommentById("1");
        System.out.println(comment);
    }

    /**
     * 保存一个评论
     */
    @Test
    public void testSaveComment(){
        Comment comment=new Comment();
        comment.setArticleid("100000");
        comment.setContent("测试添加的数据");
        comment.setCreatedatetime(LocalDateTime.now());
        comment.setUserid("1003");
        comment.setNickname("凯撒大帝");
        comment.setState("1");
        comment.setLikenum(0);
        comment.setReplynum(0);

        commentService.saveComment(comment);

        System.out.println("写入数据成功");
    }
}

  6️⃣ 可以执行测试查询、新增方法,查看是否成功

在这里插入图片描述

5.7 根据上级ID查询文章评论的分页列表

  1️⃣ CommentRepository新增方法findByParentid

瑞:注意语法格式,findBy是固定写法,ParentId 对应字段名

import com.ray.study.mongodb.article.po.Comment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * 评论的dao接口
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
public interface CommentRepository extends MongoRepository<Comment,String> {

    // 根据父id,查询子评论的分页列表
    Page<Comment> findByParentid(String parentid, Pageable pageable);

}

  2️⃣ CommentService新增方法findCommentListPageByParentid

    /**
     * 根据父id查询分页列表
     *
     * @param parentId 父ID
     * @param page     页码
     * @param size     每页显示的数据量
     */
    public Page<Comment> findCommentListPageByParentid(String parentId, int page, int size) {
        // 为什么要page-1?因为参数穿进去的是zero-based page index. 是基于0开始的索引的页码
        return commentRepository.findByParentid(parentId, PageRequest.of(page - 1, size));
    }

  3️⃣ CommentServiceTest中新增测试方法testFindCommentListPageByParentid

    /**
     * 测试根据父id查询子评论的分页列表
     */
    @Test
    public void testFindCommentListPageByParentid(){
        Page<Comment> pageResponse = commentService.findCommentListPageByParentid("3", 1, 2);
        System.out.println("----总记录数:"+pageResponse.getTotalElements());
        System.out.println("----当前页数据:"+pageResponse.getContent());
    }

  4️⃣ 在MongoDB 的articledb数据库下的comment中添加一条parentid为 3 的数据

db.getCollection("comment").insert( {
    _id: "6",
	parentid: "3",
    articleid: "100001",
    content: "研究表明,刚烧开的水千万不能喝,因为很烫。",
    userid: "1003",
    nickname: "瑞神",
    createdatetime: ISODate("2024-05-25T15:21:12.521Z"),
    likenum: NumberInt("486"),
    state: "1"
} );

  5️⃣ 运行测试方法testFindCommentListPageByParentid,结果如下,能查到一条数据

----总记录数:1
----当前页数据:[Comment{id='6', content='研究表明,刚烧开的水千万不能喝,因为很烫。', publishtime=null, userid='1003', nickname='瑞神', createdatetime=2024-05-25T23:21:12.521, likenum=486, replynum=null, state='1', parentid='3', articleid='100001'}]

在这里插入图片描述

5.8 MongoTemplate实现评论点赞(修改操作)

推荐使用MongoTemplate类来实现对某列的操作

  引入:以下为效率低的实现示例,CommentService新增updateThumbup方法

    /**
     * 点赞-效率低
     */
    public void updateCommentThumbupToIncrementingOld(String id) {
        Comment comment = CommentRepository.findById(id).get();
        comment.setLikenum(comment.getLikenum() + 1);
        CommentRepository.save(comment);
    }

  以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加 1 就可以了,没必要查询出所有字段修改后再更新所有字段。(蝴蝶效应)

  所以我们可以使用MongoTemplate类来实现对某列的操作,如下

  1️⃣ CommentService中注入MongoTemplate

    // 注入MongoTemplate
    @Resource
    private MongoTemplate mongoTemplate;

  2️⃣ CommentService中添加方法updateCommentLikenum

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
 
    /**
     * 点赞数+1
     */
    public void updateCommentLikenumThumbup(String id) {
        // 查询对象
        Query query = Query.query(Criteria.where("_id").is(id));

        // 更新对象
//        Update update = Update.update(key, value)
        Update update = new Update();
        // 局部修改,相当于$set
//        update.set(key, value)
        // 对赞数列递增1
//        update.inc("likenum", 1);
        update.inc("likenum");

        // 更新点赞数
        // 参数1:查询对象
        // 参数2:更新对象
        // 参数3:集合的名字或实体类的类型Comment.class
        mongoTemplate.updateFirst(query, update, "comment");
    }

  3️⃣ CommentServiceTest中添加测试方法testUpdateCommentLikenumThumbup

    /**
     * 点赞数+1
     */
    @Test
    public void testUpdateCommentLikenumThumbup() {
        System.out.println("点赞前:" + commentService.findCommentById("3"));
        // 对3号文档的点赞数+1
        commentService.updateCommentLikenumThumbup("3");
        System.out.println("点赞后:" + commentService.findCommentById("3"));
    }

  4️⃣ 运行测试方法testUpdateCommentLikenumThumbup,结果如下,likenum 从 666 增长为 667

点赞前:Comment{id='3', content='我一直喝凉开水,冬天夏天都喝。', publishtime=null, userid='1004', nickname='杰克船长', createdatetime=2019-08-06T09:05:06.321, likenum=666, replynum=null, state='1', parentid='null', articleid='100001'}
点赞后:Comment{id='3', content='我一直喝凉开水,冬天夏天都喝。', publishtime=null, userid='1004', nickname='杰克船长', createdatetime=2019-08-06T09:05:06.321, likenum=667, replynum=null, state='1', parentid='null', articleid='100001'}

附:完整的代码

  article【瑞_MongoDB_案例-文章评论】的完整源码的某度网盘链接如下,需要自取

链接:https://pan.baidu.com/s/1FMNAZNkXYm8kSbv18A6RDw?pwd=a7r4
提取码:a7r4

项目架构图

在这里插入图片描述

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 http://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.7.12</version>
        <relativePath/>
    </parent>

    <groupId>com.ray.study.mongodb-study</groupId>
    <artifactId>article</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml
spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
      host: 192.168.133.131
      # 数据库
      database: articledb
      # 默认端口是27017
      port: 27017
      # 方式二:使用uri连接
#      uri: mongodb://192.168.133.131:27017/articledb
ArticleApplication
package com.ray.study.mongodb.article;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 启动类
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@SpringBootApplication
public class ArticleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ArticleApplication.class, args);
    }
}
Comment
package com.ray.study.mongodb.article.po;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 文章评论实体类
 *
 * <p>把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。</p>
 * <p>@Document(collection="mongodb 对应 collection 名")</p>
 * <p>若未加 @Document ,该 bean save 到 mongo 的 comment collection</p>
 * <p>若添加 @Document ,则 save 到 comment collection</p>
 * <p></p>
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@Document(collection="comment") // 可以省略,如果省略,则默认使用类名小写映射集合
@CompoundIndex( def = "{'userid': 1, 'nickname': -1}") // 复合索引
public class Comment implements Serializable {
    // 主键标识,该属性的值会自动对应mongodb的主键字段"_id",如果该属性名就叫“id”,则该注解可以省略,否则必须写
    @Id
    private String id; // 主键

    // 该属性对应mongodb的字段的名字,如果一致,则无需该注解
    @Field("content")
    private String content;// 吐槽内容

    private Date publishtime;// 发布日期

    // 添加了一个单字段的索引
    @Indexed
    private String userid; // 发布人ID

    private String nickname; // 昵称

    private LocalDateTime createdatetime; // 评论的日期时间

    private Integer likenum; // 点赞数

    private Integer replynum; // 回复数

    private String state; // 状态

    private String parentid; // 上级ID

    private String articleid; // 文章ID

    //getter and setter.....

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Date getPublishtime() {
        return publishtime;
    }

    public void setPublishtime(Date publishtime) {
        this.publishtime = publishtime;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public LocalDateTime getCreatedatetime() {
        return createdatetime;
    }

    public void setCreatedatetime(LocalDateTime createdatetime) {
        this.createdatetime = createdatetime;
    }

    public Integer getLikenum() {
        return likenum;
    }

    public void setLikenum(Integer likenum) {
        this.likenum = likenum;
    }

    public Integer getReplynum() {
        return replynum;
    }

    public void setReplynum(Integer replynum) {
        this.replynum = replynum;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getParentid() {
        return parentid;
    }

    public void setParentid(String parentid) {
        this.parentid = parentid;
    }

    public String getArticleid() {
        return articleid;
    }

    public void setArticleid(String articleid) {
        this.articleid = articleid;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id='" + id + '\'' +
                ", content='" + content + '\'' +
                ", publishtime=" + publishtime +
                ", userid='" + userid + '\'' +
                ", nickname='" + nickname + '\'' +
                ", createdatetime=" + createdatetime +
                ", likenum=" + likenum +
                ", replynum=" + replynum +
                ", state='" + state + '\'' +
                ", parentid='" + parentid + '\'' +
                ", articleid='" + articleid + '\'' +
                '}';
    }
}

CommentRepository
package com.ray.study.mongodb.article.dao;

import com.ray.study.mongodb.article.po.Comment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * 评论的dao接口
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
public interface CommentRepository extends MongoRepository<Comment,String> {

    // 根据父id,查询子评论的分页列表
    Page<Comment> findByParentid(String parentid, Pageable pageable);

}
CommentService
package com.ray.study.mongodb.article.service;

import com.ray.study.mongodb.article.dao.CommentRepository;
import com.ray.study.mongodb.article.po.Comment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
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.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * 评论的业务层
 *
 * @author LiaoYuXing-Ray
 * @version 1.0
 * @createDate 2024/5/25 13:32
 **/
@Service
public class CommentService {
    // 注入dao
    @Resource
    private CommentRepository commentRepository;

    /**
     * 保存一个评论
     */
    public void saveComment(Comment comment) {
        // 如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键
        // 设置一些默认初始值。。。
        // 调用dao
        commentRepository.save(comment);
    }


    /**
     * 更新评论
     */
    public void updateComment(Comment comment) {
        // 调用dao
        commentRepository.save(comment);
    }

    /**
     * 根据id删除评论
     */
    public void deleteCommentById(String id) {
        // 调用dao
        commentRepository.deleteById(id);
    }

    /**
     * 查询所有评论
     */
    public List<Comment> findCommentList() {
        // 调用dao
        return commentRepository.findAll();
    }

    /**
     * 根据id查询评论
     */
    public Comment findCommentById(String id) {
        // 调用dao
        return commentRepository.findById(id).get();
    }

    /**
     * 根据父id查询分页列表
     *
     * @param parentId 父ID
     * @param page     页码
     * @param size     每页显示的数据量
     */
    public Page<Comment> findCommentListPageByParentid(String parentId, int page, int size) {
        // 为什么要page-1?因为参数穿进去的是zero-based page index. 是基于0开始的索引的页码
        return commentRepository.findByParentid(parentId, PageRequest.of(page - 1, size));
    }


    // 注入MongoTemplate
    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 点赞数+1
     */
    public void updateCommentLikenumThumbup(String id) {
        // 查询对象
        Query query = Query.query(Criteria.where("_id").is(id));

        // 更新对象
//        Update update = Update.update(key, value)
        Update update = new Update();
        // 局部修改,相当于$set
//        update.set(key, value)
        // 对赞数列递增1
//        update.inc("likenum", 1);
        update.inc("likenum");

        // 更新点赞数
        // 参数1:查询对象
        // 参数2:更新对象
        // 参数3:集合的名字或实体类的类型Comment.class
        mongoTemplate.updateFirst(query, update, "comment");
    }
}

CommentServiceTest
package com.ray.study.mongodb.article.service;


import com.ray.study.mongodb.article.ArticleApplication;
import com.ray.study.mongodb.article.po.Comment;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;


@SpringBootTest(classes = ArticleApplication.class)
public class CommentServiceTest {
    // 注入Service
    @Resource
    private CommentService commentService;

    /**
     * 查询所有数据
     */
    @Test
    public void testFindAll() {
        List<Comment> list = commentService.findCommentList();
        System.out.println(list);
    }

    /**
     * 测试根据id查询
     */
    @Test
    public void testFindCommentById() {
        Comment comment = commentService.findCommentById("1");
        System.out.println(comment);
    }

    /**
     * 保存一个评论
     */
    @Test
    public void testSaveComment() {
        Comment comment = new Comment();
        comment.setArticleid("100000");
        comment.setContent("测试添加的数据");
        comment.setCreatedatetime(LocalDateTime.now());
        comment.setUserid("1003");
        comment.setNickname("凯撒大帝");
        comment.setState("1");
        comment.setLikenum(0);
        comment.setReplynum(0);

        commentService.saveComment(comment);

        System.out.println("写入数据成功");
    }

    /**
     * 测试根据父id查询子评论的分页列表
     */
    @Test
    public void testFindCommentListPageByParentid() {
        Page<Comment> pageResponse = commentService.findCommentListPageByParentid("3", 1, 2);
        System.out.println("----总记录数:" + pageResponse.getTotalElements());
        System.out.println("----当前页数据:" + pageResponse.getContent());
    }


    /**
     * 点赞数+1
     */
    @Test
    public void testUpdateCommentLikenumThumbup() {
        System.out.println("点赞前:" + commentService.findCommentById("3"));
        // 对3号文档的点赞数+1
        commentService.updateCommentLikenumThumbup("3");
        System.out.println("点赞后:" + commentService.findCommentById("3"));
    }
}




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
为什么会这样[user_mongo@nosql01 replicaset]$ cd /opt [user_mongo@nosql01 opt]$ ll total 0 drwxr-xr-x. 3 root root 25 Mar 16 17:08 servers drwxr-xr-x. 2 root root 51 Mar 16 17:10 software [user_mongo@nosql01 opt]$ tar -zxvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/MPL-2 tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/MPL-2: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/README tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/README: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos: Cannot open: No such file or directory tar: Exiting with failure status due to previous errors [user_mongo@nosql01 opt]$ tar -zcvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ tar: Cowardly refusing to create an empty archive Try `tar --help' or `tar --usage' for more information.
最新发布
06-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑞486

你的点赞评论收藏才更是动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值