[008-05].第5节.文章评论

5 文章评论

5.1 需求分析:

  • 1.文章示例参考,讨论早晨空腹喝水,是对还是错,需要实现以下功能:
    • 基本增删改查API
    • 根据文章id查询评论
    • 评论点赞
      在这里插入图片描述

5.2 表结构分析设计

a.数据库:articledb:

在这里插入图片描述


5.3 技术选型

a.mongodb-driver

b.SpringDataMongoDB

  • 1.SpringData家族成员之一,用于操作MongoDB的持久层框架是SpringDataMongoDB,封装了底层的mongodb-driver
  • 2.官网主页

5.4 文章微服务模块搭建:

a.搭建项目工程article,pom.xml引入依赖:
<?xml version=" 1. 0 " encoding="UTF- 8 "?>
<project xmlns="http://maven.apache.org/POM/ 4. 0. 0 "
xmlns:xsi="http://www.w 3 .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>cn.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>
b.创建application.yml:
spring:
#数据源配置
	data:
		mongodb:
			# 主机地址
			host: 192.168.40.141
			# 数据库
			database: articledb
			# 默认端口是27017
			port: 27017
			#也可以使用uri连接
			#uri: mongodb://192.168.40.134:27017/articledb
c.创建启动类
package cn.itcast.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);
	}
}
d.启动项目,看是否能正常启动,控制台没有错误。

5.5 文章评论实体类的编写:

a.创建实体类,创建包cn.itcast.article,包下建包po用于存放实体类,创建实体类

package cn.itcast.article.po;

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 java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;

/**
* 文章评论实体类
*/
//把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。
//@Document(collection="mongodb 对应 collection 名")
// 若未加 @Document ,该 bean save 到 mongo 的 comment collection
// 若添加 @Document ,则 save 到 comment collection
@Document(collection="comment")//可以省略,如果省略,则默认使用类名小写映射集合
//复合索引
// @CompoundIndex( def = "{'userid': 1 , 'nickname': - 1 }")
public class Comment implements Serializable {
	//主键标识,该属性的值会自动对应mongodb的主键字段"_id",如果该属性名就叫“id”,则该注解可以省略,否则必须写
	@Id
	private String id;//主键
	//该属性对应mongodb的字段的名字,如果一致,则无需该注解
	@Field("content")
	
	
	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;
	//getter and setter.....
	
	public String getId() {
	return id;
}

public void setId(String id) {
	this.id = id;
}

public String getContent() {
	return content;
}

public void setContent(String content) {
	this.content = content;
}

public Date getPublishtime() {
return publishtime;
}

public void setPublishtime(Date publishtime) {
	this.publishtime = publishtime;
}

public String getUserid() {
	return userid;
}

public void setUserid(String userid) {
	this.userid = userid;
}

public String getNickname() {
	return nickname;
}

public void setNickname(String nickname) {
	this.nickname = nickname;
}

public LocalDateTime getCreatedatetime() {
	return createdatetime;
}

public void setCreatedatetime(LocalDateTime createdatetime) {
	this.createdatetime = createdatetime;
}

public Integer getLikenum() {
	return likenum;
}

public void setLikenum(Integer likenum) {
	this.likenum = likenum;
}

public Integer getReplynum() {
	return replynum;
}

public void setReplynum(Integer replynum) {
this.replynum = replynum;
}

public String getState() {
	return state;
}

public void setState(String state) {
	this.state = state;
}

public String getParentid() {
	return parentid;
}

public void setParentid(String parentid) {
this.parentid = parentid;
}

public String getArticleid() {
	return articleid;
}

public void setArticleid(String articleid) {
	this.articleid = 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 + '\'' +
	'}';
	}
}

b.说明:

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

b1.单字段索引注解@Indexed
  • 1.org.springframework.data.mongodb.core.index.Indexed.class
  • 2.声明该字段需要索引,建索引可以大大的提高查询效率
  • 3.Mongo命令参考:db.comment.createIndex({"userid":1})
b2.复合索引注解@CompoundIndex
  • 1.org.springframework.data.mongodb.core.index.CompoundIndex.class
  • 2.复合索引的声明,建复合索引可以有效地提高多字段的查询效率
  • 3.Mongo命令参考:db.comment.createIndex({"userid":1,"nickname":-1})

5.6 文章评论的基本增删改查

  • 1.创建数据访问接口 cn.itcast.article包下创建dao包,包下创建接口:cn.itcast.article.dao.CommentRepository
package cn.itcast.article.dao;
import cn.itcast.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> {

}
  • 2.创建业务逻辑类 cn.itcast.article包下创建service包,包下创建类
import cn.itcast.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();
	}
}
  • 3.新建Junit测试类,测试保存和查询所有:cn.itcast.article.service.CommentServiceTest
//SpringBoot的Junit集成测试
@RunWith(SpringRunner.class)
//SpringBoot的测试环境初始化,参数:启动类
@SpringBootTest(classes = ArticleApplication.class)
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(" 5 d 6 a 27 b 81 b 8 d 374798 cf 0 b 41 ");
	System.out.println(comment);
	}

在这里插入图片描述

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

  • 1.CommentRepository新增方法定义:
//根据父id,查询子评论的分页列表
Page<Comment> findByParentid(String parentid, Pageable pageable);
  • 2.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));
}
  • 3.junit测试用例:cn.itcast.article.service.CommentServiceTest
/**
* 测试根据父id查询子评论的分页列表
*/
@Test
public void testFindCommentListPageByParentid(){
	Page<Comment> pageResponse = commentService.findCommentListPageByParentid("3", 1, 2);
	System.out.println("----总记录数:"+pageResponse.getTotalElements());
	System.out.println("----当前页数据:"+pageResponse.getContent());
}
  • 4.测试:使用compass快速插入一条测试数据,数据的内容是对 3 号评论内容进行评论。
    在这里插入图片描述
  • 5.执行测试,结果:
    在这里插入图片描述

5.8 MongoTemplate实现评论点赞

a.点赞代码分析:

  • 1.我们看一下以下点赞的临时示例代码: CommentService 新增updateThumbup方法
    在这里插入图片描述

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

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

  • 1.修改CommentService
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值