目录:
一、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">
```
、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
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
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
}
```
(2)、CommentService新增方法:
```java
/**
* 根据上级id分页查询
*/
public Page
return commentRepository.findByParentid(parentid, PageRequest.of(page - 1, size));
}
```
(3)、CommentServiceTest测试类新增测试方法:
```java
@Test
public void findCommentListByParentidTest() {
Page
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
List
```
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} } }
]);
```
每天用心记录一点点,习惯很重要。在工作中不能懈怠,否则就会停滞不前,最终被淘汰。要不断进步,勇往直前,直到有一天能够像凤凰一样涅槃重生。