前言
使用SpringBoot+MongoDB整合实现文章评论 的实例操作。
1、表及字段设计
数据库名称:articledb
名称 | 含义 | 类型 |
---|
_id | 主键 | ObjectId或String | articleId | 文章ID | String | content | 评论内容 | String | userId | 评论人ID | String | nickname | 评论人名称 | String | createTime | 创建时间 | Date | likeNum | 点赞数量 | Int32 | replyNum | 回复数量 | Int32 | state | 状态(0:不可见;1:可见;) | String | parentId | 父级评论ID(0为顶级) | String |
2、引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
3、yml配置
spring:
data:
mongodb:
uri: mongodb://127.0.0.1:27017/articledb
4、实体类创建
@Document(collection = "comment")
@Data
public class Comment implements Serializable {
@Id
private String id;
private String articleId;
@Field("content")
private String content;
private String userId;
private String nickName;
private LocalDateTime createTime;
private Integer likeNum;
private Integer replyNum;
private String state;
private String parentId;
}
5、Repository
5.1、基础实现
通过实现MongoRepository<T, ID> 接口,创建Repository 类,其中T 表示实体类的class,ID 表示主键的数据类型,比如:
public interface CommentRepository extends MongoRepository<Comment, String> {}
在实现MongoRepository<T, ID> 接口后,会默认实现以下接口:
<S extends T> List<S> saveAll(Iterable<S> var1);
List<T> findAll();
List<T> findAll(Sort var1);
<S extends T> S insert(S var1);
<S extends T> List<S> insert(Iterable<S> var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2);
Optional<T> findById(ID var1);
boolean existsById(ID var1);
Iterable<T> findAll();
Iterable<T> findAllById(Iterable<ID> var1);
long count();
void deleteById(ID var1);
void delete(T var1);
void deleteAll(Iterable<? extends T> var1);
void deleteAll();
5.2、方法查询
除此之外也可以根据具体的方法名称进行查询相应内容,比如:findByName(String name) 、findByNameAndUserId(String name,String userId)
5.3、语句查询
通过@Query 编写类似sql的查询语句,支持动态传入参数,比如:
@Query(value="{\"username\":{\"$regex\":?0},\"age\":{\"$gte\":?1,\"$lte\": ?2}}")
Page<User> findByNameAndAgeRange(String name,int age,int ageTo,Pageable page);
6、具体实现
0、创建Repository
public interface CommentRepository extends MongoRepository<Comment, String> {
}
1、新增数据
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@PostMapping
public void saveComment(@RequestBody Comment comment) {
int id = (int) (Math.random() * 10000000);
int userId = (int) (Math.random() * 10);
int articleId = (int) (Math.random() * 10);
comment.setId(id + "");
comment.setReplyNum(articleId);
comment.setLikeNum(userId);
comment.setArticleId(articleId + "");
comment.setUserId(userId + "");
comment.setNickName("测试人员");
comment.setParentId("0");
comment.setState("1");
comment.setContent("测试内容");
comment.setCreateTime(System.currentTimeMillis());
commentRepository.save(comment);
List<Comment> list = new ArrayList<>();
for (int i = 0; i <= 2; i++) {
Comment comment2 = new Comment();
BeanUtils.copyProperties(comment, comment2);
int newId = (int) (Math.random() * 100000);
int newUserId = (int) (Math.random() * 10);
int newArticleId = (int) (Math.random() * 10);
comment2.setId(newId + "");
comment2.setReplyNum(articleId);
comment2.setLikeNum(userId);
comment2.setArticleId(newArticleId + "");
comment2.setUserId(newUserId + "");
comment.setNickName("测试人员");
comment.setParentId("0");
comment.setState("1");
comment.setContent("测试内容");
comment2.setCreateTime(System.currentTimeMillis());
list.add(comment2);
}
commentRepository.saveAll(list);
}
}
2、修改数据
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@PutMapping
public void updateComment(@RequestBody Comment comment) {
comment.setId("1847892");
comment.setNickName("测试人员-修改");
comment.setParentId("0");
comment.setState("1");
comment.setContent("测试内容");
comment.setCreateTime(System.currentTimeMillis());
commentRepository.save(comment);
}
}
3、删除数据
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@DeleteMapping("/{id}")
public void deleteCommentById(@PathVariable("id") String id) {
commentRepository.deleteById(id);
}
@DeleteMapping("/condition")
public void deleteCommentByArticleId() {
Query query = new Query(Criteria.where("articleId").is("10"));
mongoTemplate.remove(query, Comment.class);
}
}
4、根据ID查询
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@GetMapping("/{id}")
public Object findCommentById(@PathVariable("id") String id) {
return commentRepository.findById(id);
}
}
5、聚合查询
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@GetMapping("/agg")
public ResponseObject agg() {
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.group("userId", "articleId").count().as("userNum"),
Aggregation.skip(1L),
Aggregation.limit(10),
Aggregation.sort(Sort.Direction.DESC, "userNum")
);
AggregationResults<BasicDBObject> basicDBObjects = mongoTemplate.aggregate(aggregation, Comment.class, BasicDBObject.class);
System.out.println("basicDBObjects:");
for (DBObject obj : basicDBObjects) {
System.out.println(obj);
}
Aggregation aggregation2 = Aggregation.newAggregation(
Aggregation.match(Criteria.where("likeNum").gte(1).lte(10).and("articleId").in("4", "5")),
Aggregation.group("userId").count().as("userNum"),
Aggregation.match(Criteria.where("userNum").gte(2))
);
AggregationResults<BasicDBObject> basicDBObjects2 = mongoTemplate.aggregate(aggregation2, Comment.class, BasicDBObject.class);
System.out.println("basicDBObjects2:");
for (DBObject obj : basicDBObjects2) {
System.out.println(obj);
}
Aggregation aggregation3 = Aggregation.newAggregation(
Aggregation.match(Criteria.where("likeNum").gte(1).lte(10)),
Aggregation.group("userId").sum("likeNum").as("likeNumSum")
.avg("likeNum").as("likeNumAvg")
);
AggregationResults<BasicDBObject> basicDBObjects3 = mongoTemplate.aggregate(aggregation3, Comment.class, BasicDBObject.class);
System.out.println("basicDBObjects3:");
for (DBObject obj : basicDBObjects3) {
System.out.println(obj);
}
Aggregation aggregation4 = Aggregation.newAggregation(
Aggregation.group("userId")
.addToSet("articleId").as("setList")
.push("articleId").as("pushList")
);
AggregationResults<BasicDBObject> basicDBObjects4 = mongoTemplate.aggregate(aggregation4, Comment.class, BasicDBObject.class);
System.out.println("basicDBObjects4:");
for (DBObject obj : basicDBObjects4) {
System.out.println(obj);
}
}
}
6、列表分页+条件+排序查询
为了实现统一的分页查询,封装分页工具类:PageBuilder 、NewPageBean ,代码如下: PageBuilder:
import org.springframework.data.mongodb.core.query.Query;
public class PageBuilder {
public static void startPage(Query query, Integer pageSize, Integer pageNum) {
if (pageSize == null || pageNum == null) {
pageSize = 10;
pageNum = 1;
}
int offset = (pageNum - 1) * pageSize;
query.skip(offset).limit(pageSize);
}
}
NewPageBean:
import com.lhz.search.model.param.PageParam;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
public class NewPageBean<T> {
private Long total;
private List<T> list;
private MyPage pageInfo;
public NewPageBean(List<T> list, Class<?> entityClass, PageParam param, MongoTemplate mongoTemplate) {
Integer pageNum = param.getPageNum();
Integer pageSize = param.getPageSize();
long totalSize = mongoTemplate.count(new Query(), entityClass);
long totalPage = totalSize % pageSize == 0 ? totalSize / pageSize : totalSize / pageSize + 1;
this.list = list;
this.total = totalSize;
MyPage page = new MyPage();
page.setTotalPage(totalPage);
page.setPageNum(pageNum);
page.setPageSize(pageSize);
page.setPreviousPage(pageNum - 1);
page.setNextPage(pageNum + 1);
this.pageInfo = page;
}
public long getNum() {
return this.total;
}
public void setNum(Long total) {
this.total = total;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public MyPage getPageInfo() {
return pageInfo;
}
public void setPageInfo(MyPage pageInfo) {
this.pageInfo = pageInfo;
}
class MyPage {
private int pageNum;
private int pageSize;
private long totalPage;
private int nextPage;
private int previousPage;
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public long getTotalPage() {
return totalPage;
}
public void setTotalPage(long totalPage) {
this.totalPage = totalPage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public int getPreviousPage() {
return previousPage;
}
public void setPreviousPage(int previousPage) {
this.previousPage = previousPage;
}
}
}
查询参数-CommentParam:
@Data
public class CommentParam extends PageParam implements Serializable {
private String articleId;
private String userId;
private String keyWord;
private String nickName;
private Long startTime;
private Long endTime;
}
Controller:
@RestController
@RequestMapping("mongo")
@Slf4j
public class CommentController {
@Resource
private CommentRepository commentRepository;
@Resource
private MongoTemplate mongoTemplate;
@GetMapping
public Object findCommentList(CommentParam param) {
Criteria criteria = new Criteria();
if (param.getArticleId() != null) {
criteria.and("articleId").is(param.getArticleId());
}
if (param.getUserId() != null) {
criteria.and("userId").is(param.getUserId());
}
if (param.getNickName() != null) {
Pattern pattern = Pattern.compile("^.*" + param.getNickName() + ".*$", Pattern.CASE_INSENSITIVE);
criteria.and("nickName").regex(pattern);
}
if (param.getKeyWord() != null) {
Pattern pattern = Pattern.compile("^.*" + param.getKeyWord() + ".*$", Pattern.CASE_INSENSITIVE);
criteria.orOperator(Criteria.where("nickName").regex(pattern), Criteria.where("content").regex(pattern));
}
if (param.getEndTime() != null && param.getStartTime() != null) {
criteria.andOperator(Criteria.where("createTime").gte(param.getStartTime()), Criteria.where("createTime").lte(param.getEndTime()));
}
Query query = new Query();
query.addCriteria(criteria);
query.with(Sort.by(Sort.Order.desc("createTime"), Sort.Order.asc("userId")));
PageBuilder.startPage(query, param.getPageSize(), param.getPageNum());
List<Comment> list = mongoTemplate.find(query, Comment.class);
return new NewPageBean<>(list, Comment.class, param, mongoTemplate);
}
}
|