目录
搭建实体类
基本的增删改查操作
分页查询
使用MongoTemplate实现复杂的功能
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
在application.yml中写配资
spring:data:mongodb:# 主机地址host: 47.115.217.159# 端口port: 27017# 数据库名称database: test
启动项目,如果成功启动,说明基础配资没有问题
搭建实体类
MongoDB中的集合结构
字段名称 | 字段含义 | 字段类型 | 备注 |
---|---|---|---|
_id | ID | ObjectId或String | Mongo的主键字段,唯一标识每条评论记录 |
articleid | 文章ID | String | 评论所属文章的唯一标识符 |
content | 评论内容 | String | 用户发表的评论内容 |
userid | 评论人ID | String | 发表评论的用户的唯一标识符 |
nickname | 评论人昵称 | String | 发表评论的用户昵称 |
createdatetime | 评论的日期时间 | Date | 评论创建的时间戳 |
likenum | 点赞数 | Int32 | 评论获得的点赞数量 |
replynum | 回复数 | Int32 | 评论收到的回复数量 |
state | 状态 | String | 评论的状态,"0"表示不可见,"1"表示可见 |
parentid | 上级ID | String | 如果为"0",表示这是文章的顶级评论;否则,表示这是对另一条评论的回复 |
实体类
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/*** 文章评论实体类*/
//把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。
//@Document(collection="mongodb 对应 collection 名")
@Document(collection="comment")//可以省略,如果省略,则默认使用类名小写映射集合
//复合索引
// @CompoundIndex( def = "{'userid': 1, 'nickname': -1}")
@Data
@ToString
public class Comment implements Serializable {//主键标识,该属性的值会自动对应mongodb的主键字段"_id",如果该属性名就叫“id”,则该注解可以省略,否则必须写@Idprivate String id;//主键//该属性对应mongodb的字段的名字,如果一致,则无需该注解@Field("content")private String content;//吐槽内容private Date publishtime;//发布日期//添加了一个单字段的索引@Indexedprivate String userid;//发布人IDprivate String nickname;//昵称private LocalDateTime createdatetime;//评论的日期时间private Integer likenum;//点赞数private Integer replynum;//回复数private String state;//状态private String parentid;//上级IDprivate String articleid;
}
说明:
索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。
1)单字段索引注解@Indexed
声明该字段需要索引,建索引可以大大的提高查询效率。
2)复合索引注解@CompoundIndex
复合索引的声明,建复合索引可以有效地提高多字段的查询效率。
基本的增删改查操作
(1)创建数据访问接口
public interface CommentDao extends MongoRepository<Comment,String> {
}
MongoRepository这个类它封装了很多基本的MongoDB操作,类似于关系型数据库的mybatis-plus。
(2)创建业务逻辑类
@Service
public class CommentService {//注入dao@Autowiredprivate CommentDao commentDao;/*** 保存一个评论* @param comment*/public void saveComment(Comment comment){//如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键//设置一些默认初始值。。。//调用daocommentDao.save(comment);}/*** 更新评论* @param comment*/public void updateComment(Comment comment){//调用daocommentDao.save(comment);}/*** 根据id删除评论* @param id*/public void deleteCommentById(String id){//调用daocommentDao.deleteById(id);}/*** 查询所有评论* @return*/public List<Comment> findCommentList(){//调用daoreturn commentDao.findAll();}/*** 根据id查询评论* @param id* @return*/public Comment findCommentById(String id){//调用daoreturn commentDao.findById(id).get();}}
(3)新建测试类,测试保存和查询所有:
@SpringBootTest
class ApplicationTests {//注入Service@Autowiredprivate CommentService commentService;/*** 保存一个评论*/@Testpublic void testSaveComment(){Comment comment=new Comment();comment.setArticleid("100000");comment.setContent("测试添加的数据");comment.setCreatedatetime(LocalDateTime.now());comment.setUserid("1003");comment.setNickname("凯撒大帝");comment.setState("1");comment.setLikenum(0);comment.setReplynum(0);commentService.saveComment(comment);}/*** 查询所有数据*/@Testpublic void testFindAll(){List<Comment> list = commentService.findCommentList();for (Comment comment : list) {System.out.println(comment);}}/*** 测试根据id查询*/@Testpublic void testFindCommentById(){Comment comment = commentService.findCommentById("1");System.out.println(comment);}}
保存评论测试结果:
查询所有评论测试结果
根据Id查询测试结果
分页查询
需求:查询UserId相同的全部数据,并且分页显示
实现:
(1)CommentDao新增方法定义
@Repository
public interface CommentDao extends MongoRepository<Comment,String> {Page<Comment> findAllByUserid(String userid, Pageable pageable);
}
这里面定义方法必须按照指定的格式来定义,比如想要查询方法,就需要以findBy开头,By后面的要与形参的第一个参数名称相同。
(2)CommentService新增方法
public Page<Comment> findCommentByUserId(String id,int page, int size){return commentDao.findAllByUserid(id,PageRequest.of(page-1, size)); }
(3)测试用例
@Testpublic void testFindCommentListPageByParentid(){Page<Comment> pageResponse = commentService.findCommentByUserId( "1003",1, 2);System.out.println("----总记录数:"+pageResponse.getTotalElements());System.out.println("----当前页数据:");for (Comment comment : pageResponse.getContent()) {System.out.println(comment);}}
运行结果
使用MongoTemplate实现复杂的功能
前面MongoDB自动提供的那些功能都比较基础,功能都比较单一,如果要实现功能性复杂一点的语句,就需要借助MongoTemplate来实现。
需求:将指定id的likenum加1
根据上面的基本功能实现
/**
* 点赞-效率低
* @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
@AutowiredMongoTemplate 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.classmongoTemplate.updateFirst(query,update,"comment");}
(2)测试
@Testpublic void testUpdateCommentLikenum(){//对3号文档的点赞数+1System.out.println("修改之前的数据:");System.out.println(commentService.findCommentById("3").getLikenum());commentService.updateCommentLikenum("3");System.out.println("修改之后的数据:");System.out.println(commentService.findCommentById("3").getLikenum());}
运行结果