一、创建集合与索引 / 引入依赖 / 写入配置
1.mongo客户端
db.comment.insertMany([
{ "commentid" : "1", "state" : 1, "parentid" : "0", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "哈哈", "nickname" : "梨花带雨", "likenum" : 16, "unlikenum" : 7, "replynum" : 0 },
{ "commentid" : "2", "state" : 1, "parentid" : "0", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "什么", "nickname" : "杏花带雨", "likenum" : 56, "unlikenum" : 7, "replynum" : 0 },
{ "commentid" : "3", "state" : 1, "parentid" : "0", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "bajc", "nickname" : "海棠带雨", "likenum" : 56, "unlikenum" : 7, "replynum" : 0 },
{ "commentid" : "4", "state" : 1, "parentid" : "0", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "cdbica", "nickname" : "迎春花带雨", "likenum" : 56, "unlikenum" : 7, "replynum" : 2 },
{ "commentid" : "5", "state" : 1, "parentid" : "4", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "r", "nickname" : "玫瑰花带雨", "likenum" : 56, "unlikenum" : 7, "replynum" : 0 },
{ "commentid" : "6", "state" : 1, "parentid" : "4", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "bciadc", "nickname" : "满天星带雨", "likenum" : 56, "unlikenum" : 7, "replynum" : 1 },
{ "commentid" : "7", "state" : 1, "parentid" : "5", "userid" : 17, "publishtime" : ISODate("2022-05-13T01:41:17.816Z"), "comment" : "ocasoaiji", "nickname" : "桃花带雨", "likenum" : 56, "unlikenum" : 0, "replynum" : 0 },
{ "commentid" : "8", "state" : 1, "parentid" : "0", "comment" : "我看你", "publishtime" : ISODate("2022-05-13T04:45:49.616Z"), "userid" : 17, "nickname" : "mup", "likenum" : 8, "unlikenum" : 0, "replynum" : 0 }
])
db.comment.createIndex({commentid:1},{unique:true})
2.pom.xml
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> <version>2.3.0.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.3.0.RELEASE</version> <scope>test</scope> </dependency>
3.application-dev.yml
#开发环境
spring:
#mongodb
data:
mongodb:
host: 127.0.0.1
database: comments
port: 27017
二、Java代码demo
1.Comment 实体类
1 package com.miaoshaproject.comment.pojo; 2 3 import org.springframework.data.annotation.Id; 4 import org.springframework.data.mongodb.core.index.CompoundIndex; 5 import org.springframework.data.mongodb.core.index.CompoundIndexes; 6 import org.springframework.data.mongodb.core.index.Indexed; 7 import org.springframework.data.mongodb.core.mapping.Document; 8 9 import java.io.Serializable; 10 import java.util.Date; 11 12 /** 13 * @Author wangshuo 14 * @Date 2022/5/12, 21:43 15 * Please add a comment 16 */ 17 @Document(collection = "comment")//绑定mongodb集合 18 //@CompoundIndex(def = "{'commentid':1,'comment':-1}"):添加复合索引,索引建议用小黑窗创建 19 public class Comment implements Serializable { 20 21 //主键id 22 @Id 23 private String id; 24 25 //评论id 26 private String commentid; 27 28 //评论内容 29 //@Field("comment"): 对应的mongodb字段名,若这里的命名与mongodb的名字一样就不需要加这个注解了 30 private String comment; 31 32 //发布日期 33 private Date publishtime; 34 35 //添加单列索引 36 @Indexed 37 private Integer userid; 38 39 //用户昵称 40 private String nickname; 41 42 private Integer likenum; 43 44 private Integer unlikenum; 45 46 //回复数 47 private Integer replynum; 48 49 //状态:1.评论正常 2.评论违规被折叠 3.已删除 50 private Integer state; 51 52 //子评论属性:上一级id 53 private String parentid; 54 55 public String getId() { 56 return id; 57 } 58 59 public void setId(String id) { 60 this.id = id; 61 } 62 63 @Override 64 public String toString() { 65 return "Comment{" + 66 "commentid='" + commentid + '\'' + 67 ", comment='" + comment + '\'' + 68 ", publishtime=" + publishtime + 69 ", userid=" + userid + 70 ", nickname='" + nickname + '\'' + 71 ", likenum=" + likenum + 72 ", unlikenum=" + unlikenum + 73 ", replynum=" + replynum + 74 ", state='" + state + '\'' + 75 ", parentid='" + parentid + '\'' + 76 '}'; 77 } 78 79 public String getCommentid() { 80 return commentid; 81 } 82 83 public void setCommentid(String commentid) { 84 this.commentid = commentid; 85 } 86 87 public String getComment() { 88 return comment; 89 } 90 91 public void setComment(String comment) { 92 this.comment = comment; 93 } 94 95 public Date getPublishtime() { 96 return publishtime; 97 } 98 99 public void setPublishtime(Date publishtime) { 100 this.publishtime = publishtime; 101 } 102 103 public Integer getUserid() { 104 return userid; 105 } 106 107 public void setUserid(Integer userid) { 108 this.userid = userid; 109 } 110 111 public String getNickname() { 112 return nickname; 113 } 114 115 public void setNickname(String nickname) { 116 this.nickname = nickname; 117 } 118 119 public Integer getLikenum() { 120 return likenum; 121 } 122 123 public void setLikenum(Integer likenum) { 124 this.likenum = likenum; 125 } 126 127 public Integer getUnlikenum() { 128 return unlikenum; 129 } 130 131 public void setUnlikenum(Integer unlikenum) { 132 this.unlikenum = unlikenum; 133 } 134 135 public Integer getReplynum() { 136 return replynum; 137 } 138 139 public void setReplynum(Integer replynum) { 140 this.replynum = replynum; 141 } 142 143 public Integer getState() { 144 return state; 145 } 146 147 public void setState(Integer state) { 148 this.state = state; 149 } 150 151 public String getParentid() { 152 return parentid; 153 } 154 155 public void setParentid(String parentid) { 156 this.parentid = parentid; 157 } 158 }
2.CommentRepository dao层接口,继承MongoRepository
1 package com.miaoshaproject.comment.dao; 2 3 import com.miaoshaproject.comment.pojo.Comment; 4 import org.springframework.data.domain.Page; 5 import org.springframework.data.domain.PageRequest; 6 import org.springframework.data.mongodb.repository.MongoRepository; 7 import org.springframework.data.mongodb.repository.Query; 8 9 import java.util.List; 10 11 /** 12 * @Author wangshuo 13 * @Date 2022/5/13, 8:47 14 * 继承MongoRepository,绑定集合 15 */ 16 public interface CommentRepository extends MongoRepository<Comment, String> { 17 18 //方法名不要写错,第二个参数用于分页 19 Page<Comment> findByParentid(String parentid, PageRequest pageable); 20 21 //使用@Query的原生查询语句的方式查询 22 //使用这种方式方法名可以自定义 23 @Query(value = "{ parentid: ?0 }" ,sort = "{publishtime : -1}") 24 List<Comment> selectSortPagingDataByParentId(String parentid); 25 }
3.CommentService
1 package com.miaoshaproject.comment.service; 2 3 import com.miaoshaproject.comment.dao.CommentRepository; 4 import com.miaoshaproject.comment.pojo.Comment; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.data.domain.Page; 7 import org.springframework.data.domain.PageRequest; 8 import org.springframework.data.mongodb.core.MongoTemplate; 9 import org.springframework.data.mongodb.core.query.Criteria; 10 import org.springframework.data.mongodb.core.query.Query; 11 import org.springframework.data.mongodb.core.query.Update; 12 import org.springframework.stereotype.Service; 13 14 import java.util.List; 15 16 /** 17 * @Author wangshuo 18 * @Date 2022/5/13, 8:49 19 * Please add a comment 20 */ 21 @Service 22 public class CommentService { 23 24 @Autowired 25 CommentRepository commentRepository; 26 @Autowired 27 MongoTemplate mongoTemplate; 28 29 public void saveComment(Comment comment) { 30 commentRepository.save(comment); 31 } 32 33 public void updateComment(Comment comment) { 34 commentRepository.save(comment); 35 } 36 37 public List<Comment> findCommentList() { 38 return commentRepository.findAll(); 39 } 40 41 public Comment findCommentById(String id) { 42 return commentRepository.findById(id).get(); 43 } 44 45 public void deleteCommentById(String id) { 46 commentRepository.deleteById(id); 47 } 48 49 public Page<Comment> findByParentId(String parentid, int page, int size) { 50 51 //需要注意默认page是从0开始的,为了更易于应用,我们在这里直接给他减一,这样我们查询第一页的时候就可以直接传入参数1 52 Page<Comment> byParentid = commentRepository.findByParentid(parentid, PageRequest.of(page - 1, size)); 53 return byParentid; 54 } 55 56 //使用MongoTemplate来进行操作,好处是在一些情境下可以减少IO操作 57 public void incrCommentLikeNum(String id) { 58 59 //参数1 查询条件 可以一直and 60 Query query = Query.query(Criteria.where("commentid").is(id))/*.addCriteria()*/; 61 //参数2 更新条件 62 Update update = new Update(); 63 update.inc("likenum"); 64 //.updateFirst 修改一条 .updateMulti 修改多条 65 mongoTemplate.updateFirst(query, update, Comment.class); 66 } 67 68 public List<Comment> selectSortPagingDataByParentId(String parentid) { 69 return commentRepository.selectSortPagingDataByParentId(parentid); 70 } 71 }
三、单元测试代码是否正常
-
CommentServiceTest
1 package com.miaoshaproject; 2 3 import com.miaoshaproject.comment.pojo.Comment; 4 import com.miaoshaproject.comment.service.CommentService; 5 import com.miaoshaproject.demo.SnowFlakeID; 6 import com.miaoshaproject.service.impl.OrderServiceImpl; 7 import org.junit.Test; 8 import org.junit.runner.RunWith; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.boot.test.context.SpringBootTest; 11 import org.springframework.data.domain.Page; 12 import org.springframework.test.context.junit4.SpringRunner; 13 14 import javax.annotation.Resource; 15 import java.util.Date; 16 import java.util.List; 17 18 /** 19 * @Author wangshuo 20 * @Date 2022/5/13, 9:42 21 * 依赖于spring-boot-starter-test的Test 22 */ 23 @RunWith(SpringRunner.class) 24 @SpringBootTest 25 public class CommentServiceTest { 26 27 @Autowired 28 CommentService commentService; 29 @Autowired 30 OrderServiceImpl orderService; 31 32 @Test 33 public void testFindCommentList() { 34 35 List<Comment> commentList = commentService.findCommentList(); 36 for (Comment comment : commentList) { 37 System.out.println(comment); 38 } 39 } 40 41 @Test 42 public void testSaveComment(){ 43 44 Comment comment = new Comment(); 45 comment.setComment("我看你"); 46 //自定义算法生成 47 //comment.setCommentid(orderService.generateOrderNO()); 48 //基于雪花算法生成 49 SnowFlakeID idWorker = new SnowFlakeID(0, 0); 50 String s = String.valueOf(idWorker.nextId()); 51 System.out.println(s); 52 comment.setCommentid(s); 53 comment.setLikenum(8); 54 comment.setNickname("mup"); 55 //父级ID 56 comment.setParentid("0"); 57 comment.setPublishtime(new Date()); 58 comment.setReplynum(0); 59 comment.setState(1); 60 comment.setUserid(17); 61 comment.setUnlikenum(0); 62 commentService.saveComment(comment); 63 } 64 65 //条件查询和分页:查询根据子评论ID查询父评论详情 66 @Test 67 public void testFindByParentId(){ 68 69 Page<Comment> page = commentService.findByParentId("4", 1, 5); 70 System.out.println(page.getTotalElements()); 71 for (Comment comment : page.getContent()) { 72 System.out.println(comment); 73 } 74 } 75 76 //根据ID 喜欢数加一 77 @Test 78 public void testIncrCommentLikeNum(){ 79 80 commentService.incrCommentLikeNum("974733071427305472"); 81 } 82 83 /* 84 关于@Query分页: 85 问题: 在互联网发展的今天,大部分数据的体量都是庞大的,跳页的需求将消耗更多的内存和cpu,对应的就是查询慢。 86 当然,如果数量不大,如果不介意慢一点,那么skip也不是啥问题,关键要看业务场景。 87 看起来,分页已经实现了,但是官方文档并不推荐,说会扫描全部文档,然后再返回结果。 88 The cursor.skip() method requires the server to scan from the beginning of the input results set before beginning to return results. As the offset increases, cursor.skip() will become slower. 89 所以,需要一种更快的方式。其实和mysql数量大之后不推荐用limit m,n一样,解决方案是先查出当前页的第一条,然后顺序数pageSize条。MongoDB官方也是这样推荐的。 90 来看看大厂们怎么做的 91 Google最常用了,看起来是有跳页选择的啊。再仔细看,只有10页,多的就必须下一页,并没有提供一共多少页,跳到任意页的选择。这不就是我们的find-condition-then-limit方案吗,只是他的一页数量比较多,前端或者后端把这一页给切成了10份。 92 同样,看Facebook,虽然提供了总count,但也只能下一页。 93 其他场景,比如Twitter,微博,朋友圈等,根本没有跳页的概念的。 94 */ 95 96 @Test 97 public void selectSortPagingDataByParentId(){ 98 99 List<Comment> comments = commentService.selectSortPagingDataByParentId("4"); 100 for (Comment comment : comments) { 101 System.out.println(comment); 102 } 103 } 104 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16267967.html
浙公网安备 33010602011771号