SpringBoot整合MongoDB
先大体了解下项目结构:
1.pom 引入 mongodb 依赖
1 2 3 4 | <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> |
2 配置文件,application.properties 文件
1 2 3 4 5 | #spring.data.mongodb.host= 127.0 . 0.1 #spring.data.mongodb.port= 27017 #spring.data.mongodb.database=books ###这种类似于关系型数据库url配置 spring.data.mongodb.uri=mongodb: //127.0.0.1:27017/books |
3. 建立 mongdb 文档映射实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @Document (collection = "comment" ) //如果省略,默认类名小写 //复合索引 //@CompoundIndex(def="{'userId':1},{'nickName':-1}") public class Comment implements Serializable { @Id //对应comment中的_id private String id; @Field ( "content" ) //属性对应mongodb字段名,如果一致,无须该注解 private String content; //吐槽内容 private String articleId; //文章id private Date publishTime; //发布日期 @Indexed //添加一个单字段的索引 private String userId; //发布人id private String nickName; //发布人昵称 private Date createDateTime; //评论的日期时间 private Integer likeNum; //点赞数 private Integer replyNum; //回复数 private String state; //状态 private String parentId; //上级id .................... } |
SpringBoot 中 MongoDB 常用注解如下:
@Document
标注在实体类上,把一个 java 类声明为 mongodb 的文档,可以通过 collection 参数指定这个类对应的文档。类似于 hibernate 的 entity 注解,标明由 mongo 来维护该表。
@id
主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束。如果自己不设置 @Id 主键,mongo 会自动生成一个唯一主键,并且插入时效率远高于自己设置主键。
在实际业务中不建议自己设置主键,应交给 mongo 自己生成,自己可以设置一个业务 id,如 int 型字段,用自己设置的业务 id 来维护相关联的表。
@Indexed
声明该字段需要加索引,加索引后以该字段为条件检索将大大提高速度。
唯一索引的话是 @Indexed(unique = true)。
也可以对数组进行索引,如果被索引的列是数组时,MongoDB 会索引这个数组中的每一个元素。
也可以对整个 Document 进行索引,排序是预定义的按插入 BSON 数据的先后升序排列。
@CompoundIndex
复合索引,加复合索引后通过复合索引字段查询将大大提高速度。
@Field
属性对应 mongodb 字段名,如果一致,无须该注解
4.service 业务层
CommonService, 操作 mongo 的具体业务类
采用了 Repository 和 MongoTemplate 两种方式来实现的,其中 Repository 提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。
MongoTemplate核心操作类:Criteria 和 Query
-
Criteria类:封装所有的语句,以方法的形式查询。
-
Query类:将语句进行封装或者添加排序之类的操作。
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | @Service public class CommentService { @Autowired private CommentRepository commentRepository; @Autowired private MongoTemplate mongoTemplate; /** * 保存一个评论 * @param comment */ public void saveComment(Comment comment){ commentRepository.save(comment); // mongoTemplate.save(comment); // mongoTemplate.insert(comment); } /** * 批量保存评论 * @param < */ public void mutilSaveComment(List<Comment> list){ commentRepository.saveAll(list); // mongoTemplate.insertAll(list); } /** * 更新一个评论 * @param comment */ public void updateComment(Comment comment){ commentRepository.save(comment); } /** * 查询全部评论 * @return */ public List<Comment> findCommentAll(){ // return commentRepository.findAll(); return mongoTemplate.findAll(Comment. class ); } /** * 条件查询 * @return */ public List<Comment> findCommentByContion(Query query){ return mongoTemplate.find(query,Comment. class ); } /** * 查询全部评论通过id排序 * @return */ public List<Comment> findCommentAllOrder(){ // return commentRepository.findAll(Sort.by(Sort.Order.desc("_id"))); Query query= new Query(); query.with(Sort.by(Sort.Direction.DESC, "id" )); return mongoTemplate.find(query,Comment. class ); } /** * 通过id查询评论 * @return */ public Comment findCommentById(String id){ //return commentRepository.findById(id).get(); return mongoTemplate.findById(id,Comment. class ); } /** * 通过父id分页查询 * @param parentId * @param page * @param size * @return */ public Page<Comment> findByparentIdPage1(String parentId, int page, int size){ return commentRepository.findByParentId(parentId, PageRequest.of(page- 1 ,size)); } public List<Comment> findByparentIdPage2(String parentId, int page, int size){ Query query=Query.query(Criteria.where( "parentId" ).is(parentId)); query.with(PageRequest.of(page- 1 ,size)); return mongoTemplate.find(query,Comment. class ); } /** * 通过id删除 * @param id */ public void deleteById(String id){ // commentRepository.deleteById(id); Comment comment= new Comment(); comment.setId(id); mongoTemplate.remove(comment); } /** * 删除全部数据 * @param */ public void deleteAll(){ commentRepository.deleteAll(); } /** * 批量删除 * @param */ public void deleteMulti(List<Comment> list){ commentRepository.deleteAll(list); } /** * 点赞数加一 * @param id */ public void updateCommentLikeNumm(String id){ //点赞数加一 效率低,增加id开销 // Comment comment=commentRepository.findById(id).get(); // comment.setLikeNum(comment.getLikeNum()+1); // commentRepository.save(comment); //查询对象 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" ); //查询对象 更新对象 集合的名称或实体类的类型Comment.class mongoTemplate.updateFirst(query,update, "comment" ); } /** * 统计 * @return */ public Long commentCount(Query query){ return mongoTemplate.count(query,Comment. class ); } } |
5.dao 层
dao 层 CommentRepository 继承 MongoRepository,MongoRepository 中已经预定义了一些增删查的方法,根据 JPA 的命名规范可以定义一些查询方法,不需要具体实现,底层会帮你实现。
1 2 3 4 5 | public interface CommentRepository extends MongoRepository<Comment,String> { //新增按父id分页查询 Page<Comment> findByParentId(String parentId,Pageable pageable); } |
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 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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | @RunWith (SpringRunner. class ) @SpringBootTest public class CommentServiceTest { @Autowired private CommentService commentService; /** * 新增单个评论 */ @Test public void saveCommentTest(){ Comment comment= new Comment(); //comment.setId("2"); comment.setArticleId( "777" ); comment.setContent( "添加数据测试" ); comment.setPublishTime( new Date()); comment.setUserId( "1001" ); comment.setNickName( "张三" ); comment.setCreateDateTime( new Date()); comment.setLikeNum( 1 ); comment.setReplyNum( 0 ); comment.setState( "1" ); comment.setParentId( "0" ); commentService.saveComment(comment); } /** * 批量新增 */ @Test public void mutilSaveComment(){ List<Comment> list= new ArrayList<>(); Comment comment; for ( int i= 1 ;i<= 10 ;i++){ comment= new Comment(); comment.setId( "" +i); comment.setArticleId( "" +i); comment.setContent( "添加数据测试" +i); comment.setPublishTime( new Date()); comment.setUserId( "1001" ); comment.setNickName( "张三" ); comment.setCreateDateTime( new Date()); comment.setLikeNum( 0 ); comment.setReplyNum( 0 ); comment.setState( "1" ); comment.setParentId( "0" ); list.add(comment); } commentService.mutilSaveComment(list); } /** * 查询全部 */ @Test public void findCommentListTest() { List<Comment> list=commentService.findCommentAll(); for (Comment comment:list){ System.out.println(comment); } } /** * 通过id排序 */ @Test public void findCommentListOrderTest() { List<Comment> list=commentService.findCommentAllOrder(); for (Comment comment:list){ System.out.println(comment); } } /** * 通过id删除 */ @Test public void findCommentById() { Comment comment=commentService.findCommentById( "1" ); System.out.println(comment); } /** * 通过父id分页查询1 */ @Test public void findByParentId(){ Page<Comment> page=commentService.findByparentIdPage1( "0" , 1 , 10 ); System.out.println(page.getTotalElements()); System.out.println(page.getContent()); } /** * 通过父id分页查询2 */ @Test public void findByparentIdPage2(){ List<Comment> list=commentService.findByparentIdPage2( "0" , 1 , 10 ); for (Comment comment1:list){ System.out.println(comment1); } } /** * 通过id删除评论 */ @Test public void deleteById(){ commentService.deleteById( "1" ); } /** * 删除全部 */ @Test public void deleteAll(){ commentService.deleteAll(); } /** * 批量删除 */ @Test public void deleteMulti(){ List<Comment> list= new ArrayList<>(); Comment comment; for ( int i= 1 ;i<= 10 ;i++) { comment = new Comment(); comment.setId( "" + i); list.add(comment); } commentService.deleteMulti(list); } /** * 多条件查询in */ @Test public void findCommentByContion(){ List<String> list= new ArrayList<>(); list.add( "1" ); list.add( "2" ); list.add( "3" ); //查询对象 Query query=Query.query(Criteria.where( "_id" ).in(list)); List<Comment> list2=commentService.findCommentByContion(query); for (Comment comment1:list2){ System.out.println(comment1); } } /** * 多条件查询大于小于等于 */ @Test public void findCommentContionByGtLt(){ //查询对象 Query query=Query.query(Criteria.where( "likeNum" ).gte( 2 ).lte( 6 )); List<Comment> list =commentService.findCommentByContion(query); for (Comment comment1:list){ System.out.println(comment1); } } /** * 多条件查询and */ @Test public void findCommentContionByAnd(){ //查询对象 Query query=Query.query( new Criteria().andOperator(Criteria.where( "likeNum" ).gte( 2 ),Criteria.where( "state" ).is( "1" ))); List<Comment> list =commentService.findCommentByContion(query); for (Comment comment1:list){ System.out.println(comment1); } } /** * 多条件查询or */ @Test public void findCommentContionByOr(){ //查询对象 Query query=Query.query( new Criteria().orOperator(Criteria.where( "likeNum" ).gte( 2 ),Criteria.where( "state" ).is( "0" ))); List<Comment> list =commentService.findCommentByContion(query); for (Comment comment1:list){ System.out.println(comment1); } } /** * 更新 点赞数加一 */ @Test public void updateCommentLikeNumm(){ commentService.updateCommentLikeNumm( "1" ); } /** * 统计查询 */ @Test public void commentCount(){ Query query=Query.query(Criteria.where( "likeNum" ).gte( 2 )); Query query1= new Query(); Long count1=commentService.commentCount(query); Long count2=commentService.commentCount(query1); System.out.println( "点赞数大于等于2的文档有=======" +count1); System.out.println( "统计总数=======" +count2); } } |
到此为止, 我们已经在 SpringBoot 项目中引入了 MongoDB, 通过 MongoRepository 和 MongoTemplate 两种方式来实现了基本的增删改查操。