mongdb存储评论功能

因为之前做的项目中有用到mongdb存储评论,所以面试中会被问到怎么实现的,有什么好处,下面我写一下我会在面试中如何回答

目录

1.mongodb存储评论功能有什么优势

2.如何实现

1.表结构

2使用技术SpringDataMongoDB

3.搭建工程,pom.xml引入依赖:

4.application.yml中配置mongodb

5.文章评论实体类的编写(根据数据库表生成)

6.创建controller、sevice、mapper层

7..根据上级ID查询内推评论的分页列表

9.MongoTemplate实现评论点赞

1.mongodb存储评论功能有什么优势

1.文档存储模型:MongoDB.是一个面向文档的数据库,这意味着它存储数据的方式更接近于JSON格 式。对于文章评论,这意味着你可以将评论作为一个整体文档进行存储,而不需要像关系型数据库那样 将其分解为多个表和字段。这种灵活性使得MongoDB在处理复杂的数据结构时更加方便。 2.动态模式:MongoDB不需要预先定义数据结构,可以存储不同格式的文档。这对于文章评论来说非常 有用,因为不同的评论可能有不同的字段和格式。相比之下,MySQL等传统关系型数据库需要预先定 义表结构,这可能会限制灵活性。 3.水平扩展:MongoDB的分布式架构使其能够轻松地在多个服务器之间进行数据分区和复制,从而实现 水平扩展。这对于处理大量文章评论非常有用,因为可以很容易地增加更多的服务器来处理更高的负 载。而MySQL等传统关系型数据库在扩展方面可能面临更多的挑战。 4.查询性能:MongoDB的查询性能通常优于传统关系型数据库,尤其是在处理大量数据时。MongoDB 使用BSON(Binary JSON)格式存储数据,这使得它能够更高效地执行复杂查询和索引操作。这对于 文章评论系统来说非常重要,因为它们通常需要支持高效的查询和搜索功能。 5.实时更新:MongoDB支持实时更新和插入操作,这使得它非常适合处理实时评论。相比之下,传 统关系型数据库可能需要在更新数据时执行更多的锁定和事务操作,这可能会影响性能: 当然,MongoDB也有其局限性,例如在处理复杂的事务和连接操作方面可能不如MySQL等传统关系型数 据库。因此,在选择数据库时,需要根据具体需求和场景进行权衡。

2.如何实现

1.表结构

2使用技术SpringDataMongoDB

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

3.搭建工程,pom.xml引入依赖:

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

4.application.yml中配置mongodb

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

5.文章评论实体类的编写(根据数据库表生成)

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 + '\'' +
'}';
}
}

6.创建controller、sevice、mapper层

mapper层的CommentRepository要继承自MongoRepository并指定实体类和id

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

service里面的评论的增删改查方法

package cn.itcast.article.service;
import cn.itcast.article.dao.CommentRepository;
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();
}
}

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

9.MongoTemplate实现评论点赞

我一开始用的是根据id查出来评论的点赞数,然后+1,但是后面觉得这么做效率太低了

/**
* 点赞-效率低
* @param id
*/
public void updateCommentThumbupToIncrementingOld(String id){
Comment comment = CommentRepository.findById(id).get();
comment.setLikenum(comment.getLikenum()+1);
CommentRepository.save(comment);
}

所以后面用MongoTemplate类来实现对某列的操作从而进行了优化

@Autowired
private MongoTemplate mongoTemplate;
/**
* 点赞数+1
* @param id
*/
public void updateCommentLikenum(String id){
//查询对象
Query query=Query.query(Criteria.where("_id").is(id));
//更新对象
Update update=new Update();
//局部更新,相当于$set
// update.set(key,value)
//递增$inc
// update.inc("likenum",1);
update.inc("likenum");
//参数1:查询对象
//参数2:更新对象
//参数3:集合的名字或实体类的类型Comment.class
mongoTemplate.updateFirst(query,update,"comment");
}



//另一个版本
/**
     * 用户点赞与取消点赞评论根据评论id
     * @param commentId 被点赞评论id
     * @param isThumbup true : 点赞 ; false : 取消点赞
     */
    @Override
    public void thumbup(String commentId, Boolean isThumbup) {
        Query query = new Query(Criteria.where("cid").is(commentId)); //设置修改条件
        Update update = new Update();
        if(isThumbup){ //点赞操作
            update.inc("thumbup",1);
        }else{  //取消点赞操作
            update.inc("thumbup",-1);
        }
        mongoTemplate.updateFirst(query,update,"comment");
    }

当时还对比了redis的实现,但是发现实现起来还是mongodb比较简单,所以就用了mongodb

  • 35
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值