实现评论的基本增删改查、根据文章id查询评论、评论点赞功能
1、数据库表设计
数据库:articledb
专栏文章评论 |
comment |
|
|
字段名称 |
字段含义 |
字段类型 |
备注 |
_id |
ID |
ObjectId或String |
Mongo的主键字段 |
articleid |
文章ID |
String |
|
content |
评论内容 |
String |
|
userid |
评论人ID |
String |
|
nickname |
评论人昵称 |
String |
|
createdatetime |
评论的日期时间 |
Data |
|
likenum |
点赞数 |
Int32 |
|
replynum |
回复数 |
Int32 |
|
state |
状态 |
String |
0:不可见;1:可见; |
parentid |
上级ID |
String |
如果为0表示文章的顶级评论 |
2、技术选型
2.1 mongodb-driver(了解)
mongodb-driver是mongo官方推出的java连接mongoDB的驱动包,相当于JDBC驱动。
官方驱动说明和下载:http://mongodb.github.io/mongo-java-driver/
官方驱动示例文档:http://mongodb.github.io/mongo-java-driver/3.8/driver/getting-started/quick-start/
2.2 SpringDataMongoDB
SpringData家族成员之一,用于操作MongoDB的持久层框架,封装了底层的mongodb-driver。
官网主页: https://projects.spring.io/spring-data-mongodb/
3、文章微服务模块搭建
- 搭建项目工程article,pom.xml引入依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <?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.1</version> <relativePath/> </parent> <groupId>com.frx01</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</artifactId> </dependency>
<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> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
|
- 创建application.yml
1 2 3 4 5 6 7 8 9 10 11 12
| spring: data: mongodb: host: 192.168.72.200 database: articledb port: 27017
|
- 自动创建好启动类
1 2 3 4 5 6 7 8
| @SpringBootApplication public class ArticleApplication {
public static void main(String[] args) { SpringApplication.run(ArticleApplication.class, args); }
}
|
- 启动项目,看是否能正常启动,控制台没有错误。
4、文章评论实体类的编写
创建实体类 创建包com.frx01.article,包下建包pojo用于存放实体类,创建实体类 com.frx01.article.pojo.Comment
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Data
@Document(collection="comment")
public class Comment implements Serializable { @Id private String id; @Field("content") private String content; private Date publishtime; @Indexed private String userid; private String nickname; private LocalDateTime createdatetime; private Integer likenum; private Integer replynum; private String state; private String parentid; private String articleid;
}
|
说明:
索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。
- 单字段索引注解@Indexed
org.springframework.data.mongodb.core.index.Indexed.class
声明该字段需要索引,建索引可以大大的提高查询效率。
Mongo命令参考:
1
| db.comment.createIndex({"userid":1})
|
- 复合索引注解@CompoundIndex
org.springframework.data.mongodb.core.index.CompoundIndex.class
复合索引的声明,建复合索引可以有效地提高多字段的查询效率。
Mongo命令参考
1
| db.comment.createIndex({"userid":1,"nickname":-1})
|
5、文章评论的基本增删改查
- 创建数据访问接口 com.frx01.article包下创建dao包,包下创建接口com.frx01.article.dao.CommentRepository
1 2 3
| public interface CommentRepository extends MongoRepository<Comment,String> { }
|
- 创建业务逻辑类 com.frx01.article包下创建service包,包下创建类com.frx01.article.service.CommentService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| @Service public class CommentService {
@Autowired private CommentRepository commentRepository;
public void saveComment(Comment comment) { commentRepository.save(comment); }
public void updateComment(Comment comment) { commentRepository.save(comment); }
public void deleteCommentById(String id) { commentRepository.deleteById(id); }
public List<Comment> findCommentList() { return commentRepository.findAll(); }
public Comment findCommentById(String id) { return commentRepository.findById(id).get(); }
}
|
- 新建Junit测试类,测试保存和查询所有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest
public class ArticleApplicationTests {
@Autowired private CommentService commentService;
@Test public void testFindCommentById(){ Comment commentById = commentService.findCommentById("1"); System.out.println(commentById);
}
@Test public void testSaveComment(){ Comment comment = new Comment(); comment.setArticleid("100000"); comment.setContent("测试添加的数据"); comment.setCreatedatetime(LocalDateTime.now()); comment.setUserid("1006"); comment.setNickname("xustudyxu"); comment.setState("1"); comment.setReplynum(0); comment.setReplynum(0); commentService.saveComment(comment); }
@Test public void testFindCommentList(){ List<Comment> commentList = commentService.findCommentList(); commentList.forEach(System.out::println); }
}
|
6、根据上级ID查询文章评论的分页列表
- CommentRepository新增方法定义
1 2
| Page<Comment> findByParentid(String parentid, Pageable pageable);
|
- CommentService新增方法
1 2 3 4 5 6 7 8 9 10
|
public Page<Comment> findCommentListByParentid(String parentid,int page,int size){ return commentRepository.findByParentid(parentid, PageRequest.of(page-1,size)); }
|
- junit测试用例:
com.frx01.article.ArticleApplicationTests
1 2 3 4 5 6 7 8 9 10
|
@Test public void testFindCommentListByParentid(){ Page<Comment> pageResponse = commentService.findCommentListByParentid("3", 1, 2); System.out.println("---总记录数---:"+pageResponse.getTotalElements()); System.out.println("---当前页数据---:"+pageResponse.getContent());
}
|
- 测试
使用compass快速插入一条测试数据,数据的内容是对3号评论内容进行评论。
执行测试,结果:
1 2 3 4
| ---总记录数---:1 ---当前页数据---:[Comment(id=62b86e74258c6f1903c71820, content=:不要让惰性毁了你, publishtime=null, userid=1003, nickname=null, createdatetime=null, likenum=null, replynum=null, state=null, parentid=3, articleid=100000)]
Process finished with exit code 0
|
7、MongoTemplate实现评论点赞
我们看一下以下点赞的临时示例代码: CommentService 新增updateThumbup方法
1 2 3 4 5 6 7 8 9
|
public void updateCommentThumbupToIncrementingOld(String id){ Comment comment = commentRepository.findById(id).get(); comment.setLikenum(comment.getReplynum()+1); commentRepository.save(comment); }
|
以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加1就可以了,没必要查询出所有字段修改后再更新所有字段。(蝴蝶效应)
我们可以使用MongoTemplate类来实现对某列的操作。
- 修改CommentService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Autowired private MongoTemplate mongoTemplate;
public void updataCommentLikenum(String id){
Query query = Query.query(Criteria.where("_id").is(id));
Update update = new Update();
update.inc("likenum");
mongoTemplate.updateFirst(query,update,Comment.class); }
|
- 测试用例
1 2 3 4 5 6
| @Test public void testupdataCommentLikenum(){
commentService.updataCommentLikenum("3"); }
|
测试前:
测试后: