MongoDB入门+深入(二)--项目实战

目录

一、MongoDB项目实战

1、MongoDB技术

1.1、mongodb-driver

1.2、SpringDataMongoDB

2、项目实战

2.1、项目介绍

2.2、创建Spring Boot工程 项目名"article"

2.3、项目代码编写

2.3.1、分页查询功能

2.3.2、实现评论点赞

3、Java MongDb去重

4、查询条件


一、MongoDB项目实战

1、MongoDB技术

1.1、mongodb-driver

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

1.2、SpringDataMongoDB

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

Spring-data-mongodb官网

2、项目实战

2.1、项目介绍

文章评论的项目

需求:某网站中的文章评论。评论下还有子评论等。

需要实现以下功能:

    1、基本增删改查API

    2、根据文章ID查询评论

    3、评论点赞

表结构分析

数据库:articledb

文章评论集合:comment

字段名称字段含义字段类型备注
_idIDObjectId或StringMongoDB的主键的字段
articleid文章IDString
content评论内容String
userid评论人IDString
nickname评论人昵称String
createddatetime评论的日期时间Date
likenum点赞数Int32
replnum回复数Int32
state状态String0:不可见;1:可见;
parentid上级IDString如果为0表示文章的顶级评论
1、mongdb数据创建一条
db.comment.insert({_id:'1',content:'我相信是金子,总会有闪光之时。',publishtime:ISODate("20221022 10:10:10"),
userid:'SHK001',nickname:'悟空',createdatetime:ISODate("20221022 20:20:20"),likenum:100,
replynum:200,state:'good',parentid:'wwk334',articleid:'QW987'});

2.2、创建Spring Boot工程 项目名"article"

创建Spring Boot 工程Spring Boot入门+深入(一)

1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  
  <parent>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-parent</artifactId>
  	<version>2.1.6.RELEASE</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>

  <groupId>article</groupId>
  <artifactId>article</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>article</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven-jar-plugin.version>3.0.0</maven-jar-plugin.version>
  </properties>

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

2、application.yml

spring: 
    #数据源配置
    data: 
        mongodb: 
            #主机地址
            host: 192.168.0.125
            #数据源
            database: articledb
            #也可以使用uri连接
            #uri: mongodb://192.168.0.125:27017/articledb
            #默认端口是27017
            port: 27017
            username: admin
            password: admin

3、项目启动类

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

@SpringBootApplication
public class SpringMainApplication {

	public static void main(String[] args) {

        SpringApplication.run(SpringMainApplication.class,args);
	}

}

上述配置完成,直接启动项目

...
2022-10-22 22:40:46.556  INFO 9032 --- [168.0.125:27017] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:1}] to 192.168.0.125:27017
2022-10-22 22:40:46.562  INFO 9032 --- [168.0.125:27017] org.mongodb.driver.cluster               : Monitor thread successfully connected to server with description ServerDescription{address=192.168.0.125:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[6, 0, 2]}, minWireVersion=0, maxWireVersion=17, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=4659100}
2022-10-22 22:40:46.757  INFO 9032 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-10-22 22:40:46.761  INFO 9032 --- [           main] com.lwz.SpringMainApplication            : Started SpringMainApplication in 5.824 seconds (JVM running for 6.232)

控制台没有报错,代表启动成功。

2.3、项目代码编写

创建实体类

创建包com.lwz.article,包下建包entity用于存放实体类,创建实体类

Comment.java

package com.lwz.article.entity;

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

import org.springframework.data.annotation.Id;
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 lombok.Data;

@Data
@Document(collection = "comment")//可以省略,如果省略默认使用类名小写映射集合
//@CompoundIndex(def = "{'userid':1,'nickname':-1}") //复合索引
public class Comment implements Serializable{
	
	private static final long serialVersionUID = 1L;

	@Id
	private String id;//主键
	
	@Field("content")//该属性对应mongdb中的字段名/实体类名称和db中的名称不一致时使用
	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;
	
	@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.java

package com.lwz.article.repository;

import org.springframework.data.mongodb.repository.MongoRepository;

import com.lwz.article.entity.Comment;

public interface CommentRepository extends MongoRepository<Comment,String>{

}

CommentService ---文章评论的增删改查

package com.lwz.article.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lwz.article.entity.Comment;
import com.lwz.article.repository.CommentRepository;

@Service
public class CommentService {

	@Autowired
	private CommentRepository commentRepository;
	
	/**
	 * 保存评论
	 */
	public void saveComment(Comment comment) {
		commentRepository.save(comment);
	}
	
	/**
	 * 更新评论
	 */
	public void updateComment(Comment comment) {
		commentRepository.save(comment);
	}
	
	/**
	 * 根据ID删除评论
	 */
	public void deleteCommentById(String id) {
		commentRepository.deleteById(id);
	}
	
	/**
	 * 查询所有评论
	 */
	public List<Comment> findCommentList() {
		return commentRepository.findAll();
	}
	
	/**
	 * 根据ID查询评论
	 */
	public Comment findCommentById(String id) {
		return commentRepository.findById(id).get();
	}
}

CommentServiceTest测试类

package com.lwz.article.service;

import java.util.List;

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.test.context.junit4.SpringRunner;

import com.lwz.article.entity.Comment;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CommentServiceTest {

	@Autowired
	private CommentService commentService;
	
	@Test
	public void findCommentListTest() {
		List<Comment> commentList = commentService.findCommentList();
		System.out.println(commentList);
	}
}

启动测试类进行测试:

错误1:

Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server 192.168.0.125:27017. The full response is { "ok" : 0.0, "errmsg" : "Authentication failed.", "code" : 18, "codeName" : "AuthenticationFailed" }
	at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:179)

解决方式:

    MongoDB中每个数据库之间是相互独立的,都有独立的权限,正确的做法是使用root账号在【将要操作的数据库】中创建一个【子账号】,在用这个子账号连接mongo:

>use articledb
 
switched to db articledb
 
> db.createUser({user:"admin",pwd:"admin",roles:[{role:"dbOwner",db:"articledb"}]})
...

错误2:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2022-10-22'; nested exception is java.lang.IllegalArgumentException
	at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:112)

解决方式:

实体类Date类型和数据库中数据格式,创建mongdb时间数据使用ISODate函数

db.comment.insert({_id:'1',content:'我相信是金子,总会有闪光之时。',publishtime:ISODate("20221022 10:10:10"),
userid:'SHK001',nickname:'悟空',createdatetime:ISODate("20221022 20:20:20"),likenum:100,
replynum:200,state:'good',parentid:'wwk334',articleid:'QW987'});

问题解决后,再次启动测试类,成功!

控制台会打印如下结果:

[Comment [id=1, content=我相信是金子,总会有闪光之时。, publishtime=Sat Oct 22 18:10:10 CST 2022, userid=SHK001, nickname=悟空, createdatetime=2022-10-23T04:20:20, likenum=100, replynum=200, state=good, parentid=wwk334, articleid=QW987]]
2.3.1、分页查询功能

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

(1)、CommentRepository.java新增方法

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;

import com.lwz.article.entity.Comment;

public interface CommentRepository extends MongoRepository<Comment,String>{

	Page<Comment> findByParentid(String parentid,Pageable pageable);
	
}

(2)、CommentService新增方法

	/**
	 * 根据上级id分页查询
	 */
	public Page<Comment> findCommentListByParentid(String parentid,int page,int size) {
		return commentRepository.findByParentid(parentid,PageRequest.of(page-1, size));
	}

(3)、CommentServiceTest测试类新增测试方法

	@Test
	public void findCommentListByParentidTest() {
		Page<Comment> page = commentService.findCommentListByParentid("wwk334",1,2);
		System.out.println(page.getTotalElements());
		System.out.println(page.getContent());
	}

执行测试类:结果

1
[Comment [id=1, content=我相信是金子,总会有闪光之时。, publishtime=Sat Oct 22 18:10:10 CST 2022, userid=SHK001, nickname=悟空, createdatetime=2022-10-23T04:20:20, likenum=100, replynum=200, state=good, parentid=wwk334, articleid=QW987]]
2.3.2、实现评论点赞

方法1:

	/**
	 * 更新点赞数
	 */
	public void updateCommentLikenumById(String id) {
		Comment comment = commentRepository.findById(id).get();
		comment.setLikenum(comment.getLikenum()+1);
		commentRepository.save(comment);
	}

方法2:

我们可以使用MongoTemplate类来实现对某列的操作。

(1)、修改CommentService

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;

--------------------------------------------------------
	@Autowired
	private MongoTemplate mongoTemplate;

	/**
	 * 更新点赞数
	 */
	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);
	}

(2)、CommentServiceTest测试类新增测试方法

	@Test
	public void updateCommentLikenum() {
		Comment comment = commentService.findCommentById("1");
		System.out.println(comment.getLikenum());
		commentService.updateCommentLikenum("1");
		Comment comment1 = commentService.findCommentById("1");
		System.out.println(comment1.getLikenum());
	}

测试结果:

100
101

3、Java MongDb去重

MongoCollection<Document> collection = database.getCollection("collectionName");
List<String> uniqueValues = collection.distinct("fieldName", String.class).into(new ArrayList<>());

4、查询条件

Document doc = new Document();
doc.put("age",new Document("$gte",18));
doc.put("age",new Document("$lte",30));

MongoDB入门+深入(一)

每天⽤⼼记录⼀点点。内容也许不重要,但习惯很重要!
干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

杀神lwz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值