5-MongoDB实战演练
5.1 需求分析
某头条的文章评论业务如下:
早晨空腹喝水,是对还是错?
外从小喝凉水,冰水,也没见伤亡率就试我大天朝高多少?喝热水喝开水是当年我国建国初期
不少人认为,早起喝杯水,能够起到补水乃至减肥的作用.
生条件差,水不烧开了喝细菌多容易致病,而习惯性传下来喝开水而己,并不是什么别的原因
我们不应该把清晨浪费在手机上,健康很重要,杯温水幸福你我他
研究表明,刚烧开的水干万不能喝,因为烫嘴
我夏天空膜喝凉开水,冬天喝温开水
中间一条线两边是饭店17天前
我一直喝凉开水,冬天夏天都喝
厚德载物4426998517天有
|惊鸿照影|17天前
工人日报2019-08-0508:41:50
河畔半守护为伊人17天前
[捂脸[捂脸]岁月不饶人
专家说不能空腹吃饭
64条评论
FENGBETTA17天前
回复,5条回复V
你还年轻,火力旺.
回复收起回复人
TEAWEB17天前
南街村夫17天前
南街村夫17天前
写下您的评论..
查看更多评平论
12凸口
4仓回
4仓口
6凸回
8E
回复
回复
回复
评平论
回复
回复
2凸口
06
3F
需要实现以下功能:
1)基本增删改查API
2)根据文章id查询评论
3)评论点赞
5.2 表结构分析
数据库:articledb
5.3 技术选型
5.3.1 mongodb-driver(了解)
mongodb-driver是mongo官方推出的java连接mongoDB的驱动包,相当于JDBC驱动。我们通过一个入门的案例来了解mongodb-driver的基本使用。
5.3.2 SpringDataMongoDB
SpringData家族成员之一,用于操作MongoDB的持久层框架,封装了底层的mongodb-driver。
官网主页: https://projects.spring.io/spring-data-mongodb/
5.4 文章微服务模块搭建
(1)搭建项目工程article,pom.xml引入依赖
(2)创建application.yml
(3)创建启动类
cn.itcast.article.ArticleApplication
(4)启动项目,看是否能正常启动,控制台没有错误。
5.5 文章评论实体类的编写
创建实体类 创建包cn.itcast.article,包下建包po用于存放实体类,创建实体类
cn.itcast.article.po.Comment
说明:
索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。
1)单字段索引注解@Indexed
org.springframework.data.mongodb.core.index.Indexed.class
声明该字段需要索引,建索引可以大大的提高查询效率。
Mongo命令参考:
db.comment.createIndex({"userid":1})
2)复合索引注解@CompoundIndex
org.springframework.data.mongodb.core.index.CompoundIndex.class
复合索引的声明,建复合索引可以有效地提高多字段的查询效率。
Mongo命令参考:
db.comment.createIndex({"userid":1,"nickname":-1})
5.6 文章评论的基本增删改查
(1)创建数据访问接口 cn.itcast.article包下创建dao包,包下创建接口
cn.itcast.article.dao.CommentRepository
(2)创建业务逻辑类 cn.itcast.article包下创建service包,包下创建类
cn.itcast.article.service.CommentService
(3)新建Junit测试类,测试保存和查询所有:
cn.itcast.article.service.CommentServiceTest
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.8 MongoTemplate实现评论点赞
我们看一下以下点赞的临时示例代码: CommentService 新增updateThumbup方法
/** * 点赞-效率低 * @param id */ public void updateCommentThumbupToIncrementingOld(String id){ Comment comment = CommentRepository.findById(id).get(); comment.setLikenum(comment.getLikenum()+1); CommentRepository.save(comment); }
以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加1就可以了,没必要查询出所有字段修改后再更新所有字段。我们可以使用MongoTemplate类来实现对某列的操作。
(1)修改CommentService
//注入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"); }
(2)测试用例:
cn.itcast.article.service.CommentServiceTest
/** * 点赞数+1 */ @Test public void testUpdateCommentLikenum(){ //对3号文档的点赞数+1 commentService.updateCommentLikenum("3"); }
执行测试用例后,发现点赞数+1了: