MongoDB快速上手指南:SpringBoot整合MongoDB

2022-08-0222:21:35数据库教程Comments1,293 views字数 9207阅读模式

5.1 需求分析

这里会结合一个具体的业务场景(小案例),对用户评论进行CRUD文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

在这个案例中主要的需求是:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

  • 基本增删改查API
  • 根据文章id查询评论
  • 评论点赞

文章示例参考:早晨空腹喝水,是对还是错?www.toutiao.com/a6721476546…文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

5.2 表结构分析

数据库:articledb,集合就用我们上面一直在使用的comment文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

5.3 技术选型

5.3.1 mongodb-driver(了解)

mongodb-driver是mongo官方推出的java连接mongoDB的驱动包,相当于JDBC驱动。我们通过一个入门的案例来了解mongodb-driver 的基本使用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

5.3.2 SpringDataMongoDB

SpringData家族成员之一,用于操作MongoDB的持久层框架,封装了底层的mongodb-driver。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

官网主页: projects.spring.io/spring-data…文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

5.4 文章微服务模块搭建

(1)搭建项目工程article,pom.xml引入依赖:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

<?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.7.2</version>  
        <relativePath/> <!-- lookup parent from repository -->  
    </parent>  
    <groupId>com.fx</groupId>  
    <artifactId>article</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <name>article</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-data-mongodb</artifactId>  
        </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>  
        </dependency>  
    </dependencies>  

    <build>  
        <plugins>  
            <plugin>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-maven-plugin</artifactId>  
                <configuration>  
                    <excludes>  
                        <exclude>  
                            <groupId>org.projectlombok</groupId>  
                            <artifactId>lombok</artifactId>  
                        </exclude>  
                    </excludes>  
                </configuration>  
            </plugin>  
        </plugins>  
    </build>  

</project>
复制代码

(2)创建application.yml文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

spring:  
  #数据源配置  
  data:  
    mongodb:  
      # 主机地址  
      host: localhost  
      # 数据库  
      database: articledb  
      # 默认端口是27017  
      port: 27017  
      # 也可以使用uri连接  
      #uri: mongodb://192.168.40.134:27017/articledb
复制代码

(3)创建启动类文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

com.fx.article.ArticleApplication文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

package com.fx.article;  

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

@SpringBootApplication  
public class ArticleApplication {  

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

}
复制代码

我们启动一下空项目,看Mongo连接是否正常,一般就可以正常连接了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

5.5 文章评论实体类的编写

创建实体类 创建包com.fx.article,包下建包po用于存放实体类,创建实体类文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

这里有一点需要注意,因为Mongo是可以进行横向拓展的,所以可能会出现一个集合对应多个实体类的情况文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

package com.fx.article.po;  

import lombok.Data;  
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 java.io.Serializable;  
import java.time.LocalDateTime;  
import java.util.Date;  

/**  
 * <p>  
 * 文档评论实体类<br/>  
 * 把一个Java类生命为mongodb的文档,可以通过collection参数指定这个类对应的文档  
 * </p>  
 *  
 * @since 2022-07-28 20:19  
 * @author 梁峰源  
 **/  
@Data  
// 若未添加@Document注解,则该bean save到mongo的comment collection  
@Document(collection = "comment")//指定对应的集合,如果省略则默认为类名小写进行集合映射  
@CompoundIndex(def = "{'userid': 1, 'nickname' : -1}") // 添加复合索引,先按userid排,再按nickname降序排  
public class Comment implements Serializable {  
    private static final long serialVersionUID = 21218312631312334L;  
    // 主键标识,该属性的值会自动对应mongodb的主键字段`_id`, 如果该属性名叫做 `id`, 则该注解可以省略,否者必须写  
    @Id  
    private String id;//主键  
    private String content;//吐槽内容  
    private Date publishtime;//发布日期  
    // 添加了一个单子段的索引  
    @Indexed  
    private String userid;//发布人的ID  
    private String nickname;//用户昵称  
    private LocalDateTime createdatetime;//评论的日期时间  
    private Integer likenum;//点赞数  
    private Integer replaynum;//回复数  
    private String state;//状态  
    private String parentid;//上级ID  
    private String articleid;//文章id  
}
复制代码

说明: 索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。一般我们为了项目的可拓展性,会在命令行进行添加文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

1)单字段索引注解@Indexed文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

org.springframework.data.mongodb.core.index.Indexed.class文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

声明该字段需要索引,建索引可以大大的提高查询效率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

Mongo命令参考:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

db.comment.createIndex({"userid":1})
复制代码

2)复合索引注解@CompoundIndex文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

org.springframework.data.mongodb.core.index.CompoundIndex.class文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

复合索引的声明,建复合索引可以有效地提高多字段的查询效率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

Mongo命令参考:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

db.comment.createIndex({"userid":1,"nickname":-1})
复制代码

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

(1)创建数据访问接口 cn.itcast.article包下创建dao包,包下创建接口文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

com.fx.article.dao.CommentRepository文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

package com.fx.article.dao;  

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

/**  
 * <p>  
 *  
 * </p>  
 *  
 * @author 梁峰源  
 * @since 2022-07-28 20:34  
 **/public interface CommentRepository extends MongoRepository<Comment, String> {  
}
复制代码

(2)创建业务逻辑类 cn.itcast.article包下创建service包,包下创建类文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

com.fx.article.service.CommentService文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

package com.fx.article.service;  

import com.fx.article.dao.CommentRepository;  
import com.fx.article.po.Comment;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  

import java.util.List;  

/**  
 * <p>  
 * 评论service方法  
 * </p>  
 *  
 * @since 2022-07-28 20:36  
 * @author 梁峰源  
 **/  
@Service  
public class CommentService {  
    //注入dao  
    @Autowired  
    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();  
    }  

}
复制代码

(3)新建Junit测试类,测试保存和查询所有:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

com.fx.itcast.article.service.CommentServiceTest文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

package com.fx.article.service;  


import com.fx.article.po.Comment;  
import org.junit.jupiter.api.Test;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.boot.test.context.SpringBootTest;  

import java.time.LocalDateTime;  
import java.util.List;  

/**  
 * @author Eureka  
 * @version 1.0  
 * @since 2022年7月28日20:56:33  
 */@SpringBootTest  
public class CommentServiceTest {  

    @Autowired  
    private CommentService commentService;  

    /**  
     * 保存一条记录  
     */  
    @Test  
    public void testSaveComment() throws Exception {  
        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);  
        // 在查询一下这条记录,这里获取id的方式和Mybatis Plus一样,直接从实体类中获取即可  
        Comment commentById = commentService.findCommentById(comment.getId());  
        System.out.println(commentById);  
    }  

    /**  
     * 更新一条记录  
     */  
    @Test  
    public void testUpdateComment() throws Exception {  
//        Comment comment = new Comment();  
//        comment.setId("1");  
//        comment.setNickname("张三");  
        // 上面的方式会将其他字段变为空,所以可以先查询出来再更新对应字段  
        Comment comment = commentService.findCommentById("1");  
        comment.setNickname("张三");  
        // 更新这条记录  
        commentService.updateComment(comment);  
        // 打印一下这条记录  
        Comment commentById = commentService.findCommentById(comment.getId());  
        System.out.println(commentById);  
    }  

    /**  
     * Method: deleteCommentById(String id)     */    @Test  
    public void testDeleteCommentById() throws Exception {  
        commentService.deleteCommentById("1");  
    }  

    /**  
     * Method: findCommentList()     */    @Test  
    public void testFindCommentList() throws Exception {  
        List<Comment> commentList = commentService.findCommentList();  
        System.out.println(commentList);  
    }  

    /**  
     * 通过id查询一条记录  
     */  
    @Test  
    public void testFindCommentById() throws Exception {  
        Comment commentById = commentService.findCommentById("1");  
        System.out.println(commentById);  
    }  


}
复制代码

这里需要注意如果是MongoDB 6以上的版本可能打印不出来,这里可能有像MySQL中MVCC之类的同学,我换成4版本后就可以正常打印出来了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

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

(1)CommentRepository新增方法定义文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

/**  
 * 分页查询,这里的名字要根据提示来,不能写错不然会生成失败  
 */  
Page<Comment> findByUserid(String userid, Pageable pageable);
复制代码

(2)CommentService新增方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

/**  
 * 根据父id查询分页列表  
 * @param userid  
 * @param page 页码  
 * @param size 页数  
 */  
public Page<Comment> findCommentListPageByUserid(String userid,int page ,int size){  
    return commentRepository.findByUserid(userid, PageRequest.of(page-1,size));  
}
复制代码

测试文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

@Test  
void testFindCommentListPageByParentid() {  
    Page<Comment> pages = commentService.findCommentListPageByUserid("1003", 1, 3);  
    // 打印有多少条记录  
    System.out.println(pages.getTotalElements());  
    List<Comment> contentList = pages.getContent();  
    // 将所有的记录都打印出来  
    contentList.forEach(System.out::println);  
}
复制代码

5.8 MongoTemplate实现评论点赞

我们看一下以下点赞的临时示例代码: CommentService 新增updateThumbup方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

/**  
 * 点赞-效率低  
 * @param id  
 */  
public void updateCommentThumbupToIncrementingOld(String id){  
    Comment comment = commentRepository.findById(id).get();  
    comment.setLikenum(comment.getLikenum()+1);  
    commentRepository.save(comment);  
}
复制代码

以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加1就可以了,没必要查询出所有字段修改后再更新所有字 段。(蝴蝶效应)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

我们可以使用MongoTemplate类来实现对某列的操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

(1)修改CommentService文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

//注入MongoTemplate  
@Autowired  
private MongoTemplate mongoTemplate;

/**  
 * 点赞数+1  
 * @param id  
 */  
public void updateCommentLikenum(String id) {  
    //查询对象  
    Query query = Query.query(Criteria.where("_id").is(id));  
    //更新对象  
    Update update = new Update();  
    //局部更新,相当于$set  
    // update.set(key,value)    //递增$inc  
    // update.inc("likenum",1);    update.inc("likenum");  
    //参数1:查询对象  
    //参数2:更新对象  
    //参数3:集合的名字或实体类的类型Comment.class  
    mongoTemplate.updateFirst(query, update, "comment");  

    }
复制代码

(2)测试用例:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

@Test  
void testupdateCommentLikenum() {  
    // 更新之前  
    System.out.println(commentService.findCommentById("2"));  
    commentService.updateCommentLikenum("2");  
    // 更新之后  
    System.out.println(commentService.findCommentById("2"));  
}
复制代码

测试结果,可以看到数据已经增长了文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

MongoDB快速上手指南:SpringBoot整合MongoDB文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

更多的命令可以自行进行查看,这里贴一下API的地址:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

作者:是小梁同学呀
链接:https://juejin.cn/post/7126746699527094303
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/sjk/26460.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/sjk/26460.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定