目录:

一、MongoDB项目实战

1. MongoDB技术

1.1 mongodb-driver

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

1.2 SpringDataMongoDB

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

2. 项目实战

2.1 项目介绍

文章评论的项目。评论下还有子评论等。需要实现以下功能:1、基本增删改查API;2、根据文章ID查询评论;3、评论点赞。

表结构分析:

数据库:articledb

文章评论集合:comment

字段名称 | 字段含义 | 字段类型 | 备注

---|---|---|---

_id | ID | ObjectId或String | MongoDB的主键的字段

articleid | 文章ID | String |

content | 评论内容 | String |

userid | 评论人ID | String |

nickname | 评论人昵称 | String |

createddatetime | 评论的日期时间 | Date |

likenum | 点赞数 | Int32 |

replnum | 回复数 | Int32 |

state | 状态 | String | 0:不可见;1:可见;

parentid | 上级ID | String | 如果为0表示文章的顶级评论

```xml

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">

org.springframework.boot

spring-boot-starter-parent

2.1.6.RELEASE

4.0.0

article

article

0.0.1-SNAPSHOT

jar

article

http://maven.apache.org

UTF-8

3.0.0

junit

junit

test

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

org.springframework.boot

spring-boot-starter-data-mongodb

org.projectlombok

lombok

```

、applicationyml

```yaml

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、项目启动类

```java

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);

}

}

```

配置完成后,直接启动项目。

```java

import javaxpersistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

@Entity

public class MyEntity {

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

private Long id;

// 其他属性和getter、setter方法

}

```

首先,我们需要创建一个名为`com.lwz.article`的包。在这个包下,我们将创建一个名为`entity`的子包,用于存放实体类。接下来,我们将在`entity`子包中创建一个名为`Comment.java`的实体类。

以下是创建`Comment.java`实体类的步骤:

1. 打开你的IDE(例如IntelliJ IDEA或Eclipse),然后在项目结构中找到`com.lwz.article`包。如果没有这个包,请创建一个新的包。

2. 在`com.lwz.article`包下,右键单击并选择`New` > `Package`,然后输入`entity`作为新包的名称。点击`OK`按钮创建新的子包。

3. 在`entity`子包下,右键单击并选择`New` > `Java Class`,然后输入`Comment.java`作为新类的名称。点击`OK`按钮创建新的实体类。

4. 现在,你需要编写`Comment.java`文件的内容。以下是一个简单的示例:

```java

package com.lwz.article.entity;

public class Comment {

private long id; // 评论ID

private String content; // 评论内容

private String author; // 评论者

private Date createTime; // 评论创建时间

// 构造方法、getter和setter方法省略

}

```

5. 最后,保存文件并编译运行你的项目。现在你已经成功创建了一个名为`Comment.java`的实体类。

```java

package comlwz.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

```java

package com.lwz.article.repository;

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

import com.lwz.article.entity.Comment;

public interface CommentRepository extends MongoRepository {

}

```

CommentService:文章评论的增删改查服务

以下是重构后的代码,已经按照您的要求进行了格式化,并将测试类的包名改为了`cn.itcast.article.service`,以符合Java命名规范。

```java

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 {

/**

* 保存评论

*/

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 findCommentList() {

return commentRepository.findAll();

}

/**

* 根据ID查询评论

*/

public Comment findCommentById(String id) {

return commentRepository.findById(id).get();

}

}

```

请根据提供的内容完成内容重构,并保持段落结构:

```java

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 commentList = commentService.findCommentList();

System.out.println(commentList);

}

}

```

启动测试类进行测试:错误1。

解决MongoDB中的身份验证失败问题,可以尝试以下方法:

1. 使用root账号在要操作的数据库中创建一个子账号。首先切换到目标数据库,然后执行以下命令:

```

use articledb

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

```

这将在`articledb`数据库中创建一个名为`admin`的用户,并赋予其`dbOwner`角色。

2. 使用创建的子账号连接MongoDB。将上述命令中的`admin`和`articledb`替换为实际的用户名和数据库名:

```

mongo --username admin --password admin --authenticationDatabase articledb

```

3. 如果仍然遇到身份验证失败的问题,请检查MongoDB服务器的配置文件(`mongod.conf`),确保其中的`security.authorization`设置已启用。将其更改为以下内容:

```

security:

authorization: enabled

```

4. 重启MongoDB服务以使更改生效。

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类型和数据库中数据格式不一致,需要将字符串转换为ISODate类型。修改代码如下:

```java

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

```

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

控制台会打印如下结果:

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

```java

(1)、CommentRepository.java新增方法:

```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 {

Page findByParentid(String parentid, Pageable pageable);

}

```

(2)、CommentService新增方法:

```java

/**

* 根据上级id分页查询

*/

public Page findCommentListByParentid(String parentid, int page, int size) {

return commentRepository.findByParentid(parentid, PageRequest.of(page - 1, size));

}

```

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

```java

@Test

public void findCommentListByParentidTest() {

Page page = commentService.findCommentListByParentid("wwk334", 1, 2);

System.out.println(page.getTotalElements());

System.out.println(page.getContent());

}

```

执行测试类:结果。

以下是重构后的代码:

```java

/**

* 实现评论点赞

*/

public void updateCommentLikenumById(String id) {

// 更新点赞数

Comment comment = commentRepository.findById(id).get();

comment.setLikenum(comment.getLikenum() + 1);

commentRepository.save(comment);

}

```

使用MongoTemplate类来实现对某列的操作,可以修改CommentService如下:

```java

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

import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.stereotype.Service;

@Service

public class CommentService {

@Autowired

private MongoTemplate mongoTemplate;

/**

* 实现评论点赞

*/

public void updateCommentLikenumById(String id) {

// 修改某列的操作

mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is(id)), new Comment(), "likenum");

}

}

```

以下是内容重构后的代码:

```java

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;

public class CommentService {

@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);

}

}

```

测试类新增测试方法:

```java

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

import static org.junit.jupiter.api.Assertions.assertNotNull;

public class CommentServiceTest {

@Test

public void updateCommentLikenum() {

CommentService commentService = new CommentService(); //创建CommentService实例

//测试用例1:更新前查询并打印点赞数,然后更新点赞数,再次查询并打印点赞数

Comment comment = commentService.findCommentById("1"); //通过ID查找评论对象

System.out.println("点赞数 (更新前): " + comment.getLikenum()); //打印点赞数(更新前)

assertEquals(100, comment.getLikenum(), "点赞数不正确(更新前)"); //断言点赞数是否正确(更新前)

commentService.updateCommentLikenum("1"); //调用updateCommentLikenum方法更新点赞数

Comment comment1 = commentService.findCommentById("1"); //再次通过ID查找评论对象

System.out.println("点赞数 (更新后): " + comment1.getLikenum()); //打印点赞数(更新后)

assertEquals(101, comment1.getLikenum(), "点赞数不正确(更新后)"); //断言点赞数是否正确(更新后)

assertNotNull(comment1, "评论对象为null"); //断言评论对象是否为null(避免空指针异常)

}

}

```

. Java中使用MongoDB去重的方法:

```java

MongoCollection collection = database.getCollection("collectionName");

List uniqueValues = collection.distinct("fieldName", String.class).into(new ArrayList<>());

```

4. 查询条件示例:

```java

Document doc = new Document();

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

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

```

5. 查询MongoDB某个字段重复的文档:

```java

db.getCollection("xx_table").aggregate([

{ $group: { _id: "$class_name", count: { $sum: 1 } } },

{ $match: { count: { $gt: 1} } }

]);

```

每天用心记录一点点,习惯很重要。在工作中不能懈怠,否则就会停滞不前,最终被淘汰。要不断进步,勇往直前,直到有一天能够像凤凰一样涅槃重生。