MongoDB Java实战

在这里插入图片描述

📕作者简介: 过去日记,致力于Java、GoLang,Rust等多种编程语言,热爱技术,喜欢游戏的博主。
📗本文收录于MongoDB系列,大家有兴趣的可以看一看
📘相关专栏Rust初阶教程go语言基础系列、spring教程等,大家有兴趣的可以看一看
📙Java并发编程系列,设计模式系列、go web开发框架 系列正在发展中,喜欢Java,GoLang,Rust,的朋友们可以关注一下哦!


@[TOC] ## 实战 ## 表结构 存放文章评论的数据存放到MongoDB中,数据结构参考如下: 数据库:articledb
专栏文章评论comment
字段名称字段含义字段类型备注
_idIDObjectId或StringMongo的主键字段
articleid文章IDString
content评论内容String
userid评论人IDString
nickname评论人昵称String
createdatetime评论的日期时间Date
likenum点赞数Int32
replynum回复数Int32
state状态String0:不可见;1:可见
parentid上级IDString如果为0表示文章的顶级评论

项目搭建

<?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.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>itcast</groupId>
    <artifactId>article</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <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>

(2)创建application.yml

spring:
  #数据源配置
  data:
    mongodb:
      # 主机地址
      host: 192.168.218.131
      # 数据库
      database: articledb
      # 默认端口是27017
      port: 27017
      username: root
      password: "123456"
      authentication-database: admin #必须设置设置权限认证的数据库

(3)创建启动类
onenewcode.article.ArticleApplication

package onenewcode.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);
    }
 }

(4)启动项目,看是否能正常启动,控制台没有错误。

文章评论实体类的编写

创建实体类 创建包onenewcode.article,包下建包po用于存放实体类,创建实体类
onenewcode.article.po.Comment

package onenewcode.article.service;

import onenewcode.article.dao.CommentRepository;
import onenewcode.article.po.Comment;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;

@Service
public class CommentService {

    @Autowired
    private CommentRepository commentRepository;
    @Autowired
    private MongoTemplate mongoTemplate;



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

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

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

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

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


    public Page<Comment> findCommentListByParentid(String parentid,int page,int size) {
        return commentRepository.findByParentid(parentid,PageRequest.of(page-1,size));
    }

    public void updateCommentLikenum(String id){

        //  查询条件
        Query query = Query.query(Criteria.where("_id").is(id));
        //  更新条件
        Update update = new Update();
        update.inc("likenum");
        mongoTemplate.updateFirst(query,update,Comment.class);
    }
}

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

1)单字段索引注解@Indexed
org.springframework.data.mongodb.core.index.Indexed.class
声明该字段需要索引,建索引可以大大的提高查询效率。
Mongo命令参考:

db.comment.createIndex({“userid”:1})

2)复合索引注解@CompoundIndex
org.springframework.data.mongodb.core.index.CompoundIndex.class
复合索引的声明,建复合索引可以有效地提高多字段的查询效率。

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

文章评论的基本增删改查

  1. 创建数据访问接口 onenewcode.article包下创建dao包,包下创建接口
    onenewcode.article.dao.CommentRepository
package onenewcode.article.dao;
 
import onenewcode.article.po.Comment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
 //评论的持久层接口
public interface CommentRepository extends MongoRepository<Comment,String> {
  
}
  1. 创建业务逻辑类 onenewcode.article包下创建service包,包下创建类
import onenewcode.article.po.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.List;
 
//评论的业务层
@Service
 public class CommentService {
 
    //注入dao
    @Autowired
    private CommentRepository commentRepository;
    
    /**
     * 保存一个评论
     * @param comment
     */
    public void saveComment(Comment comment){
        //如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键
        //设置一些默认初始值。。。
        //调用dao
        commentRepository.save(comment);
    }
 
    /**
     * 更新评论
     * @param comment
     */
    public void updateComment(Comment comment){
        //调用dao
        commentRepository.save(comment);
    }
 
    /**
     * 根据id删除评论
     * @param id
     */
    public void deleteCommentById(String id){
        //调用dao
        commentRepository.deleteById(id);
    }
 
    /**
     * 查询所有评论
     * @return
     */
    public List<Comment> findCommentList(){
        //调用dao
        return commentRepository.findAll();
    }
 
    /**
     * 根据id查询评论
     * @param id
     * @return
     */
    public Comment findCommentById(String id){
        //调用dao
        return commentRepository.findById(id).get();
    }
 }
  1. 新建Junit测试类,测试保存和查询所有:
package onenewcode.article.service;
 
import onenewcode.article.ArticleApplication;
import onenewcode.article.po.Comment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.test.context.junit4.SpringRunner;
import java.time.LocalDateTime;
import java.util.List;
//测试评论的业务层
//SpringBoot的Junit集成测试
 //SpringBoot的测试环境初始化,参数:启动类
@SpringBootTest
public class CommentServiceTest {
 
    //注入Service
    @Autowired
    private CommentService commentService;
 
    /**
     * 保存一个评论
     */
    @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);
 
    }
 
    /**
     * 查询所有数据
     */
    @Test
    public void testFindAll(){
        List<Comment> list = commentService.findCommentList();
        System.out.println(list);
    }
    
     /**
     * 测试根据id查询
     */
    @Test
    public void testFindCommentById(){
        Comment comment = commentService.findCommentById("5d6a27b81b8d374798cf0b41");
        System.out.println(comment);
    }
}

添加结果:

在这里插入图片描述

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

  1. CommentRepository新增方法定义

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

  1. CommentService新增方法
 /**
     * 根据父id查询分页列表
     * @param parentid
     * @param page
     * @param size
     * @return
     */
    public Page<Comment> findCommentListPageByParentid(String parentid,int page ,int size){
        return commentRepository.findByParentid(parentid, PageRequest.of(page-1,size));
    }
  1. junit测试用例
 /**
     * 测试根据父id查询子评论的分页列表
     */
    @Test
    public void testFindCommentListPageByParentid(){
        Page<Comment> pageResponse = commentService.findCommentListPageByParentid("3", 1, 2);
        System.out.println("----总记录数:"+pageResponse.getTotalElements());
        System.out.println("----当前页数据:"+pageResponse.getContent());
    }

MongoTemplate实现评论点赞

以下点赞的临时示例代码: CommentService 新增updateThumbup方法

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

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

//注入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");
}
  1. 测试用例:
 /**
 * 点赞数+1
 */
 @Test
 public void testUpdateCommentLikenum(){
 //对3号文档的点赞数+1
 commentService.updateCommentLikenum("3");
 }
  • 18
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

过去日记

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值