使用 MongoDB 完成吐槽微服务以及文章评论功能
吐槽微服务
吐槽微服务项目创建(省略)
准备工作
引入依赖
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
| <?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"> <parent> <artifactId>tensquare_parent</artifactId> <groupId>com.tensquare</groupId> <version>1.0.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion>
<artifactId>tensquare_spit</artifactId>
<dependencies> <dependency> <groupId>com.tensquare</groupId> <artifactId>tensquare_common</artifactId> <version>${tensquare.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> </dependencies> </project>
|
编写application.yaml
1 2 3 4 5 6 7 8 9 10
| spring: data: mongodb: host: 192.168.136.104 port: 27017 database: spit application: name: tensquare-spit server: port: 9006
|
编写启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.tensquare.spit;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import util.IdWorker;
@SpringBootApplication public class SpitApplication { public static void main(String[] args) { SpringApplication.run(SpitApplication.class, args); }
@Bean public IdWorker idWorker(){ return new IdWorker(1, 6); } }
|
创建吐槽实体类
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
| package com.tensquare.spit.pojo;
import lombok.Data; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable; import java.util.Date;
@Data public class Spit implements Serializable {
@Id private String _id; private String content; private Date publishtime; private String userid; private String nickname; private Integer visits; private Integer thumbup; private Integer share; private Integer comment; private String state; private String parentid; }
|
CRUD实现
SpitController
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 61 62 63 64 65 66 67 68 69 70 71
| package com.tensquare.spit.controller;
import com.tensquare.spit.pojo.Spit; import com.tensquare.spit.service.SpitService; import entity.Result; import entity.StatusCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
@CrossOrigin @RestController @RequestMapping("/spit") public class SpitController {
@Autowired private SpitService spitService;
@RequestMapping(method = RequestMethod.GET) public Result findAll() { return new Result(true, StatusCode.OK, "查询成功", spitService.findAll()); }
@RequestMapping(value = "/{id}", method = RequestMethod.GET) public Result findOne(@PathVariable String id) { return new Result(true, StatusCode.OK, "查询成功", spitService.findById(id)); }
@RequestMapping(method = RequestMethod.POST) public Result add(@RequestBody Spit spit) { spitService.add(spit); return new Result(true, StatusCode.OK, "增加成功"); }
@RequestMapping(value="/{id}",method=RequestMethod.PUT) public Result update(@RequestBody Spit spit,@PathVariable String id ) { spit.set_id(id); spitService.update(spit); return new Result(true,StatusCode.OK,"修改成功"); }
@RequestMapping(value="/{id}",method=RequestMethod.DELETE) public Result deleteById(@PathVariable String id ){ spitService.deleteById(id); return new Result(true,StatusCode.OK,"删除成功"); }
}
|
SpitService
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 61 62 63 64 65
| package com.tensquare.spit.service;
import com.tensquare.spit.pojo.Spit; import com.tensquare.spit.repository.SpitRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import util.IdWorker;
import java.util.List;
@Service public class SpitService {
@Autowired private SpitRepository spitRepository;
@Autowired private IdWorker idWorker;
public List<Spit> findAll() { return spitRepository.findAll(); }
public Spit findById(String id) { Spit spit = spitRepository.findById(id).get(); return spit; }
public void add(Spit spit) { spit.set_id(idWorker.nextId() + ""); spitRepository.save(spit); }
public void update(Spit spit) { spitRepository.save(spit); }
public void deleteById(String id) { spitRepository.deleteById(id); } }
|
SpitRepository
1 2 3 4 5 6 7
| package com.tensquare.spit.repository;
import com.tensquare.spit.pojo.Spit; import org.springframework.data.mongodb.repository.MongoRepository;
public interface SpitRepository extends MongoRepository<Spit, String> { }
|
根据上级ID查询吐槽列表
SpitController新增方法
1 2 3 4 5 6 7 8 9 10 11
|
@RequestMapping(value = "/comment/{parentId}/{page}/{size}", method = RequestMethod.GET) public Result findByParentid(@PathVariable String parentId, @PathVariable int page, @PathVariable int size) { Page<Spit> pageList = spitService.findByParentid(parentId, page, size); return new Result(true, StatusCode.OK, "查询成功", new PageResult<>(pageList.getTotalElements(), pageList.getContent())); }
|
SpitService新增方法
1 2 3 4 5 6 7 8 9 10 11
|
public Page<Spit> findByParentid(String parentId, int page, int size) { return spitRepository.findByParentid(parentId, PageRequest.of(page, size)); }
|
SpitRepository新增方法
1
| Page<Spit> findByParentid(String parentId, Pageable pageable);
|
吐槽点赞
SpitController新增方法
1 2 3 4 5 6 7 8
|
@RequestMapping(value = "/thumbup/{id}", method = RequestMethod.PUT) public Result updateThumbup(@PathVariable String id) { spitService.updateThumbup(id); return new Result(true, StatusCode.OK, "点赞成功"); }
|
SpitController新增方法
1 2 3 4 5 6 7 8 9 10 11 12
|
public void updateThumbup(String id) { Optional<Spit> optionalSpit = spitRepository.findById(id); if (optionalSpit.isPresent()) { Spit spit = optionalSpit.get(); spit.setThumbup(spit.getThumbup() == null ? 0 : spit.getThumbup() + 1); } }
|
控制不能重复点赞
根据用户ID和吐槽Id进行存储,放在redis中,每次点赞前先判断是否存在该key,如果存在说明已经点过赞了,不存在执行点赞逻辑。
引入Redis依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
|
配置Redis
1 2 3 4
| spring: redis: host: 192.168.136.104 port: 6379
|
SpitController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
@RequestMapping(value = "/thumbup/{id}", method = RequestMethod.PUT) public Result updateThumbup(@PathVariable String id) { String userid = "2023"; if (redisTemplate.opsForValue().get("thumbup_" + userid + "_" + id) != null) { return new Result(false, StatusCode.REPERROR, "你已经点过赞了"); } spitService.updateThumbup(id); redisTemplate.opsForValue().set("thumbup_" + userid + "_" + id, "1"); return new Result(true, StatusCode.OK, "点赞成功"); }
|
也可以把这些逻辑放在Service
中处理。
发布吐槽逻辑修改
修改SpitService#add
方法逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public void add(Spit spit) { spit.set_id(idWorker.nextId() + ""); spit.setPublishtime(new Date()); spit.setVisits(0); spit.setShare(0); spit.setThumbup(0); spit.setComment(0); spit.setState("1"); if (spit.getParentid() != null && !"".equals(spit.getParentid())) { Query query = new Query(); query.addCriteria(Criteria.where("_id").is(spit.getParentid())); Update update = new Update(); update.inc("comment", 1); mongoTemplate.updateFirst(query, update, "spit"); } spitRepository.save(spit); }
|
文章微服务 - 评论功能
表结构分析
评论的数据非常多,而且价值相对较低,所有这里仍然采用MongoDB
进行存储。
字段名称 |
字段含义 |
字段类型 |
备注 |
_id |
ID |
文本 |
|
articleid |
文章ID |
文本 |
|
content |
评论内容 |
文本 |
|
userid |
评论人ID |
文本 |
|
parentid |
评论ID |
文本 |
如果为0表示文章的顶级评论 |
publishdate |
评论日期 |
日期 |
准备工作
文章评论功能是属于之前的文章微服务,所以这里我们回到文章微服务继续开发。
引入依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
|
配置MongoDB
1 2 3 4 5 6
| Spring: data: mongodb: host: 192.168.136.104 port: 27017 database: commentdb
|
创建评论实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.tensquare.article.pojo;
import lombok.Data;
import javax.persistence.Id; import java.io.Serializable; import java.util.Date;
@Data public class Comment implements Serializable { @Id private String _id; private String articleid; private String content; private String userid; private String parentid; private Date publishdate; }
|
新增评论
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.tensquare.article.controller;
import com.tensquare.article.pojo.Comment; import com.tensquare.article.service.CommentService; import entity.Result; import entity.StatusCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
@RestController @CrossOrigin @RequestMapping("/comment") public class CommentController {
@Autowired private CommentService commentService;
@RequestMapping(method= RequestMethod.POST) public Result save(@RequestBody Comment comment){ commentService.add(comment);
return new Result(true, StatusCode.OK, "提交成功 "); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.tensquare.article.service;
import com.tensquare.article.dao.CommentDao; import com.tensquare.article.pojo.Comment; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import util.IdWorker;
@Service public class CommentService {
@Autowired private CommentDao commentDao;
@Autowired private IdWorker idWorker;
public void add(Comment comment) { comment.setId(idWorker.nextId() + ""); commentDao.save(comment); }
}
|
实体类如果是使用lombok
的@Data
注解的话,因为是_id
所以set方法也是set_id
,我这里只所以是setId
是因为我重写了_id
的getter和setter方法。
1 2 3 4 5 6 7
| package com.tensquare.article.dao;
import com.tensquare.article.pojo.Comment; import org.springframework.data.mongodb.repository.MongoRepository;
public interface CommentDao extends MongoRepository<Comment, String> { }
|
查询指定文章的所有评论
1 2 3 4 5
| @RequestMapping(value="/article/{articleid}",method= RequestMethod.GET) public Result findByArticleid(@PathVariable String articleid){ return new Result(true, StatusCode.OK, "查询成功", commentService.findByArticleid(articleid)); }
|
1 2 3 4 5 6 7 8 9
|
public List<Comment> findByArticleid(String articleid){ return commentDao.findByArticleid(articleid); }
|
1
| List<Comment> findByArticleid(String articleid);
|
删除评论
1 2 3 4 5
| @RequestMapping(value="/{commentId}",method= RequestMethod.DELETE) public Result delete(@PathVariable String commentId){ commentService.deleteById(commentId); return Result.ok("删除成功"); }
|
1 2 3
| public void deleteById(String commentId) { commentDao.deleteById(commentId); }
|