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 两种方式来实现了基本的增删改查操。