绿色健康小清新

耐得住寂寞,守得住繁华

MongoDB

简介

MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。

它支持的数据结构非常松散,是一种类似于 JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。

MongoDB中的记录是一个文档,它是一个由字段和值对(fifield:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认 为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组

体系结构

MySQL和MongoDB对比

术语

相关术语对比

数据模型

MongoDB的最小存储单位就是文档(document)对象。文档(document)对象对应于关系型数据库的行。数据在MongoDB中以 BSON(Binary-JSON)文档的格式存储在磁盘上。

BSON(Binary Serialized Document Format)是一种类json的一种二进制形式的存储格式,简称Binary JSON。BSON和JSON一样,支持 内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。

BSON采用了类似于 C 语言结构体的名称、对表示方法,支持内嵌的文档对象和数组对象,具有轻量性、可遍历性、高效性的三个特点,可 以有效描述非结构化数据和结构化数据。这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想。

Bson中,除了基本的JSON类型:string,integer,boolean,double,null,array和object,mongo还使用了特殊的数据类型。这些类型包括 date,object id,binary data,regular expression 和code。每一个驱动都以特定语言的方式实现了这些类型,查看你的驱动的文档来获取详 细信息。

BSON数据类型参考列表:

安装并创建用户

下载镜像

1
docker pull mongo

创建容器,并挂载数据卷

1
docker run -p 27017:27017 --name mongodb -v $PWD/db:/data/db -d mongo:latest --auth

进入容器

1
docker exec -it mongodb /bin/bash

运行mongo命令

看是否能正常启动

1
mongo

创建用户和密码

使用admin用户

1
use admin

创建管理员账户并设置密码

1
db.createUser({ user: 'root', pwd: 'root', roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] });

以 admin 用户身份进入mongo

1
docker exec -it mongodb  mongo admin

进行身份验证

就是上一步创建的管理员账号密码

1
db.auth("root","root")

创建 用户、密码和数据库:

1
db.createUser({ user: 'jcl', pwd: 'jcl123456', roles: [ { role: "readWrite", db: "learn" } ] });

以 admin 用户身份进入mongo :

1
docker exec -it mongodb  mongo admin

对 zy 进行身份认证:

1
db.auth("zy","zy123456");

切换数据库

1
use app

数据库基本操作

离不开的增删改查,MongoDB 中默认的数据库为 test,如果你没有选择数据库,集合将存放在 test 数据库中,有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库

查看数据库

1
show dbs

选择和创建数据库

如果数据库不存在则自动创建,并切换

1
use learn

查看当前数据库

1
db

删除数据库

MongoDB 删除数据库的语法格式如下:

1
db.dropDatabase()

提示:主要用来删除已经持久化的数据库

集合基本操作

查看集合

1
2
3
show collections
或者
show tables

显示创建集合

1
db.createCollection(stu) 

集合的命名规范:

  • 集合名不能是空字符串""。
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以"system."开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除 非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

隐式创建集合并插入数据

当向一个集合中插入一个文档的时候,如果集合不存在,则会自动创建集合,通常我们使用隐式创建文档即可

1
2
3
4
5
6
7
8
db.stus.insert({name: "xiaoming",age: 18,gender: "male"});


# 多个插入
db.stus.insert([
{name: "zhubajie",age: 27,gender: "male"},
{name: "shaheshang",age: 27,gender: "male"}
])

删除集合

1
2
3
db.collection.drop() 

db.集合.drop()

如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。

例如:要删除stus集合

1
db.stus.drop()

文档基本操作

插入文档

1
2
3
4
5
6
7
8
9
10
 # 多个插入
db.comment.insert({
"articleid": "100000",
"content": "今天天气真好,阳光明 媚",
"userid": "1001",
"nickname": "Rose",
"createdatetime": new Date(),
"likenum": NumberInt(10),
"state": null
})

提示:

  • comment集合如果不存在,则会隐式创建
  • mongo中的数字,默认double类型,如要存整型,必须使用函数NumberInt,否则取出来就有问题了。
  • 插入当前日期使用 new Date()
  • 插入的数据没有指定 _id ,会自动生成主键值
  • 如果某字段没值,可以赋值为null,或不写该字段。

执行后,如下,说明插入一个数据成功了

注意:

  1. 文档中的键/值对是有序的。
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .和$有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)

批量插入

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
db.comment.insertMany([{
"_id": "1",
"articleid": "100001",
"content": "我们不应该把清晨浪费在手机上,健康很重要,一杯温水幸福你我 他。",
"userid": "1002",
"nickname": "相忘于江湖",
"createdatetime": new Date("2019-08- 05T22:08:15.522Z"),
"likenum": NumberInt(1000),
"state": "1"
},
{
"_id": "2",
"articleid": "100001",
"content": "我夏天空腹喝凉开水,冬天喝温开水",
"userid": "1005",
"nickname": "伊人憔 悴",
"createdatetime": new Date("2019-08-05T23:58:51.485Z"),
"likenum": NumberInt(888),
"state": "1"
},
{
"_id": "3",
"articleid": "100001",
"content": "我一直喝凉开水,冬天夏天都喝。",
"userid": "1004",
"nickname": "杰克船 长",
"createdatetime": new Date("2019-08-06T01:05:06.321Z"),
"likenum": NumberInt(666),
"state": "1"
},
{
"_id": "4",
"articleid": "100001",
"content": "专家说不能空腹吃饭,影响健康。",
"userid": "1003",
"nickname": "凯 撒",
"createdatetime": new Date("2019-08-06T08:18:35.288Z"),
"likenum": NumberInt(2000),
"state": "1"
},
{
"_id": "5",
"articleid": "100001",
"content": "研究表明,刚烧开的水千万不能喝,因为烫 嘴。",
"userid": "1003",
"nickname": "凯撒",
"createdatetime": new Date("2019-08- 06T11:01:02.521Z"),
"likenum": NumberInt(3000),
"state": "1"
}]);

提示:

插入时指定了 _id ,则主键就是该值。

异常捕获

如果某条数据插入失败,将会终止插入,但已经插入成功的数据不会回滚掉。

因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理。

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
try {  
db.comment.insertMany([{
"_id": "1",
"articleid": "100001",
"content": "我们不应该把清晨浪费在手机上,健康很重要",
"userid": "1002",
"nickname": "相忘于江湖",
"createdatetime": new Date("2019-08- 05T22:08:15.522Z"),
"likenum": NumberInt(1000),
"state": "1"
},
.............
{
"_id": "5",
"articleid": "100001",
"content": "研究表明,刚烧开的水千万不能喝,因为烫 嘴。",
"userid": "1003",
"nickname": "凯撒",
"createdatetime": new Date("2019-08- 06T11:01:02.521Z"),
"likenum": NumberInt(3000),
"state": "1"
}]);
} catch (e) {
print (e);
}

查询集合中的文档

查询所有

如果我们要查询集合的所有文档,我们输入以下命令

1
2
3
db.comment.find() 

db.comment.find({})

这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主键,当你在插入文档记录时没有指定该字段, MongoDB会自动创建,其类型是ObjectID类型。 如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也可以是MongoDB支持的任意类型.

如果我想按一定条件来查询,比如我想查询userid为1003的记录,怎么办?很简单!只 要在fifind()中添加参数即可,参数也是json格式,如 下:

1
db.comment.find({userid:'1003'})

如果你只需要返回符合条件的第一条数据,我们可以使用fifindOne命令来实现,语法和fifind一样。

如:查询用户编号是1003的记录,但只最多返回符合条件的第一条记录:

1
db.comment.findOne({userid:'1003'})

投影查询(Projection Query)

如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。

如:查询结果只显示 _id、userid、nickname :

1
db.comment.find({userid:"1003"},{userid:1,nickname:1})

如:查询结果只显示 、userid、nickname ,不显示 _id :

1
db.comment.find({userid:"1003"},{userid:1,nickname:1,_id:0})

再例如:查询所有数据,但只显示 _id、userid、nickname :

1
db.comment.find({},{userid:1,nickname:1})

统计查询

1
db.collection.count(query, options)

参数:

ParameterTypeDescription
querydocument查询选择条件。
optionsdocument可选。用于修改计数的额外选项。

【示例】

统计comment集合的所有的记录数:

1
db.comment.count()

统计userid为1003的记录条数

1
db.comment.count({userid:"1003"})

分页查询

可以使用limit()方法来读取指定数量的数据,使用skip()方法来跳过指定数量的数据

基本语法如下所示:

1
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)

如果你想返回指定条数的记录,可以在fifind方法后调用limit来返回结果(TopN),默认值20,例如

1
db.comment.find().limit(3)

skip方法同样接受一个数字参数作为跳过的记录条数。(前N个不要),默认值是0

1
db.comment.find().skip(3)

分页查询:需求:每页2个,第二页开始:跳过前两条数据,接着值显示3和4条数据

1
2
3
4
5
6
//第一页 
db.comment.find().skip(0).limit(2)
//第二页
db.comment.find().skip(2).limit(2)
//第三页
db.comment.find().skip(4).limit(2)

排序查询

sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用 于降序排列

1
2
3
db.COLLECTION_NAME.find().sort({KEY:1}) 

db.集合名称.find().sort(排序方式)

例如:

对userid降序排列,并对访问量进行升序排列

1
db.comment.find().sort({userid:-1,likenum:1})

提示:

skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。

正则查询

MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:

1
2
3
db.collection.find({field:/正则表达式/})

db.集合.find({字段:/正则表达式/})

提示:正则表达式是js的语法,直接量的写法。

例如,我要查询评论内容包含“开水”的所有文档,代码如下:

1
db.comment.find({content:/开水/})

如果要查询评论的内容中以“专家”开头的,代码如下:

1
db.comment.find({content:/^专家/})

比较查询

<, <=, >, >= 这个操作符也是很常用的,格式如下:

1
2
3
4
5
db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value 
db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value
db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value
db.集合名称.find({ "field" : { $ne: value }}) // 不等于: field != value

示例:查询评论点赞数量大于700的记录

1
db.comment.find({likenum:{$gt:NumberInt(700)}})

包含查询

包含使用$in操作符。 示例:查询评论的集合中userid字段包含1003或1004的文档

1
db.comment.find({userid:{$in:["1003","1004"]}})

不包含使用$nin操作符。 示例:查询评论集合中userid字段不包含1003和1004的文档

1
db.comment.find({userid:{$nin:["1003","1004"]}})

条件连接查询

我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。 格式为:

1
$and:[ { },{ },{ } ] 

示例:查询评论集合中likenum大于等于700 并且小于2000的文档:

1
db.comment.find({$and:[{likenum:{$gte:NumberInt(700)}},{likenum:{$lt:NumberInt(2000)}}]})

如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面 and的使用方式相同 格式为:

1
$or:[ { },{ },{ } ]

示例:查询评论集合中userid为1003,或者点赞数小于1000的文档记录

1
db.comment.find({$or:[ {userid:"1003"} ,{likenum:{$lt:1000} }]})

修改文档数据

更新文档的语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
db.collection.update(query, update, options) 

db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string> // Available starting in MongoDB 4.2
}
)

【示例】

覆盖的修改

如果我们想修改_id为1的记录,点赞量为1001,输入以下语句:

1
db.comment.update({_id:"1"},{likenum:NumberInt(1001)})

执行后,我们会发现,这条文档除了likenum字段其它字段都不见了

局部修改

为了解决这个问题,我们需要使用修改器$set来实现,命令如下:

我们想修改_id为2的记录,浏览量为889,输入以下语句:

1
db.comment.update({_id:"2"},{$set:{likenum:NumberInt(889)}})

这样就OK啦。

批量修改

更新所有用户为 1003 的用户的昵称为 凯撒大帝 。

1
2
3
4
//默认只修改第一条数据 
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒2"}})
//修改所有符合条件的数据
db.comment.update({userid:"1003"},{$set:{nickname:"凯撒大帝"}},{multi:true})

提示:如果不加后面的参数,则只更新符合条件的第一条记录

列值增长的修改

如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用 $inc 运算符来实现。

需求:对3号数据的点赞数,每次递增1

1
db.comment.update({_id:"3"},{$inc:{likenum:NumberInt(1)}})

删除文档

删除文档的语法结构:

1
db.集合名称.remove(条件)

以下语句可以将数据全部删除,请慎用

1
db.comment.remove({})

如果删除_id=1的记录,输入以下语句

1
db.comment.remove({_id:"1"})

文档替换

将指定的文档的字段值替换

1
db.users.replaceOne({username: "zhubajie"},{username: "tangsheng"})

文档删除指定字段

删除指定用户的address字段

1
db.users.update({username: "tangsheng"},{$unset: {address: 1}})

其他相关命令

[ 启动客户端 => ./bin/mongo --host 192.168.200.100 ]

1: 查看所有已经创建的数据库 => show dbs

2: 切换或者创建数据库 => use 数据库名称

3: 删除当前数据库 => db.dropDatabase()

4: 获取当前数据库的名称 => db.getName()

5: 获取当前数据库的连接地址 => db.getMongo()

7: 获取当前数据库的所有集合(表) => show cellections

8: 向集合(表)添加数据, 不存在的集合会自动创建 => db.集合名称.save(json)

9: 修改数据 => db.集合名称.update(json1, json2)

9.1: json1 为查询条件 如 {“id”: 25}

9.2: json2 为修改成 如 {“name”: “测试”}

9.3: 意思为 将 id 是 25 的所有数据的 name 字段修改为 "测试"

10: 删除数据 => db.集合名称.remove(json)

10.1: json 和 9 的 json1 相似, 为需要删除的条件

11: 查询数据 => db.结合名称.find(json)

11.1: json 和 9 的 json1 相似, 为需要查询的条件

12: 创建数据库超级管理员 => db.createUser({ user: “root”, pwd: “920619”, roles: [ { role: “root”, db: “admin” } ]})

12.1: user: 账号, pwd: 密码, db: 数据库 // 超级管理员只能在 admin 下创建

12.2: roles: 权限 有以下选择 =>

12.3: 数据库用户角色:read、readWrite;

12.4: 数据库管理角色:dbAdmin、dbOwner、userAdmin;

12.5: 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

12.6: 备份恢复角色:backup、restore;

12.7: 当前数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

12.8: 超级用户角色:root, 这里还有几个角色间接或直接提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)

12.9: 内部角色:__system

13: 重新启动mongodb登入客户端还和以前一样, 但是登入后你回答无法操作数据库

13.1: 登入用户 => use admin => db.auth(‘root’, ‘920619’) => 输出 1 表示登入成功

13.2: 超级管理员在 admin 下登入, 具体数据库的管理员在具体的数据库下登入

14: 删除用户可以直接操作 admin 下的 system.users 集合

ps:更多命令请查看官网代码

SpringBoot整合MongoDB

依赖

1
2
3
4
5
<!-- mongodb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置

1
2
3
4
5
6
7
8
9
10
11
12
13
spring:
data:
mongodb:
host: 127.0.0.1
port: 27017
username: manager
password: manager
authentication-database: admin #认证的库
database: exam #操作的库

logging:
level:
top.codekiller.test.mongodb: DEBUG #配置MongoTemplate日志

工具类

我这里是用的其他博主的测试工具类,看最下方链接处。

我对工具类进行了一些改变,原工具类的查询是传入对象,并且返回的类型也有点一言难尽,所以我用了一个泛型,直接传入类对象,方便了很多。原来的我也保留了。

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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
package top.codekiller.test.mongodb.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;

/**
* @author codekiller
* @date 2020/5/30 15:53
* Mongodb工具类
*/
@Component
public class MongodbUtils {

public static MongodbUtils mongodbUtils;

@PostConstruct
public void init() {
mongodbUtils = this;
mongodbUtils.mongoTemplate = this.mongoTemplate;
}

@Autowired
private MongoTemplate mongoTemplate;

/**
* 保存数据对象,集合为数据对象中@Document 注解所配置的collection
*
* @param obj
* 数据对象
*/
public static void save(Object obj) {
mongodbUtils.mongoTemplate.save(obj);
}

/**
* 指定集合保存数据对象
*
* @param obj
* 数据对象
* @param collectionName
* 集合名
*/
public static void save(Object obj, String collectionName) {

mongodbUtils.mongoTemplate.save(obj, collectionName);
}

/**
* 根据数据对象中的id删除数据,集合为数据对象中@Document 注解所配置的collection
*
* @param obj
* 数据对象
*/
public static void remove(Object obj) {

mongodbUtils.mongoTemplate.remove(obj);
}

/**
* 指定集合 根据数据对象中的id删除数据
*
* @param obj
* 数据对象
* @param collectionName
* 集合名
*/
public static void remove(Object obj, String collectionName) {

mongodbUtils.mongoTemplate.remove(obj, collectionName);
}

/**
* 根据key,value到指定集合删除数据
*
* @param key
* 键
* @param value
* 值
* @param collectionName
* 集合名
*/
public static void removeById(String key, Object value, String collectionName) {

Criteria criteria = Criteria.where(key).is(value);
criteria.and(key).is(value);
Query query = Query.query(criteria);
mongodbUtils.mongoTemplate.remove(query, collectionName);
}

/**
* 指定集合 修改数据,且仅修改找到的第一条数据
*
* @param accordingKey
* 修改条件 key
* @param accordingValue
* 修改条件 value
* @param updateKeys
* 修改内容 key数组
* @param updateValues
* 修改内容 value数组
* @param collectionName
* 集合名
*/
public static void updateFirst(String accordingKey, Object accordingValue, String[] updateKeys, Object[] updateValues,
String collectionName) {

Criteria criteria = Criteria.where(accordingKey).is(accordingValue);
Query query = Query.query(criteria);
Update update = new Update();
for (int i = 0; i < updateKeys.length; i++) {
update.set(updateKeys[i], updateValues[i]);
}
mongodbUtils.mongoTemplate.updateFirst(query, update, collectionName);
}

/**
* 指定集合 修改数据,且修改所找到的所有数据
*
* @param accordingKey
* 修改条件 key
* @param accordingValue
* 修改条件 value
* @param updateKeys
* 修改内容 key数组
* @param updateValues
* 修改内容 value数组
* @param collectionName
* 集合名
*/
public static void updateMulti(String accordingKey, Object accordingValue, String[] updateKeys, Object[] updateValues,
String collectionName) {

Criteria criteria = Criteria.where(accordingKey).is(accordingValue);
Query query = Query.query(criteria);
Update update = new Update();
for (int i = 0; i < updateKeys.length; i++) {
update.set(updateKeys[i], updateValues[i]);
}
mongodbUtils.mongoTemplate.updateMulti(query, update, collectionName);
}

/**
* 根据条件查询出所有结果集 集合为数据对象中@Document 注解所配置的collection
*
* @param obj
* 数据对象
* @param findKeys
* 查询条件 key
* @param findValues
* 查询条件 value
* @return
*/
public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues) {

Criteria criteria = null;
for (int i = 0; i < findKeys.length; i++) {
if (i == 0) {
criteria = Criteria.where(findKeys[i]).is(findValues[i]);
} else {
criteria.and(findKeys[i]).is(findValues[i]);
}
}
Query query = Query.query(criteria);
List<? extends Object> resultList = mongodbUtils.mongoTemplate.find(query, obj.getClass());
return resultList;
}

/**
* 指定集合 根据条件查询出所有结果集
*
* @param obj
* 数据对象
* @param findKeys
* 查询条件 key
* @param findValues
* 查询条件 value
* @param collectionName
* 集合名
* @return
*/
public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues, String collectionName) {

Criteria criteria = null;
for (int i = 0; i < findKeys.length; i++) {
if (i == 0) {
criteria = Criteria.where(findKeys[i]).is(findValues[i]);
} else {
criteria.and(findKeys[i]).is(findValues[i]);
}
}
Query query = Query.query(criteria);
List<? extends Object> resultList = mongodbUtils.mongoTemplate.find(query, obj.getClass(), collectionName);
return resultList;
}

/**
* 指定集合 根据条件查询出所有结果集 并排倒序
*
* @param obj
* 数据对象
* @param findKeys
* 查询条件 key
* @param findValues
* 查询条件 value
* @param collectionName
* 集合名
* @param sort
* 排序字段
* @return
*/
public static List<? extends Object> find(Object obj, String[] findKeys, Object[] findValues, String collectionName ,String sort) {

Criteria criteria = null;
for (int i = 0; i < findKeys.length; i++) {
if (i == 0) {
criteria = Criteria.where(findKeys[i]).is(findValues[i]);
} else {
criteria.and(findKeys[i]).is(findValues[i]);
}
}
Query query = Query.query(criteria);
query.with(new Sort(Direction.DESC, sort));
List<? extends Object> resultList = mongodbUtils.mongoTemplate.find(query, obj.getClass(), collectionName);
return resultList;
}

/**
* 根据条件查询出符合的第一条数据 集合为数据对象中 @Document 注解所配置的collection
*
* @param obj
* 数据对象
* @param findKeys
* 查询条件 key
* @param findValues
* 查询条件 value
* @return
*/
public static Object findOne(Object obj, String[] findKeys, Object[] findValues) {

Criteria criteria = null;
for (int i = 0; i < findKeys.length; i++) {
if (i == 0) {
criteria = Criteria.where(findKeys[i]).is(findValues[i]);
} else {
criteria.and(findKeys[i]).is(findValues[i]);
}
}
Query query = Query.query(criteria);
Object resultObj = mongodbUtils.mongoTemplate.findOne(query, obj.getClass());
return resultObj;
}

/**
* 指定集合 根据条件查询出符合的第一条数据
*
* @param obj
* 数据对象
* @param findKeys
* 查询条件 key
* @param findValues
* 查询条件 value
* @param collectionName
* 集合名
* @return
*/
public static Object findOne(Object obj, String[] findKeys, Object[] findValues, String collectionName) {

Criteria criteria = null;
for (int i = 0; i < findKeys.length; i++) {
if (i == 0) {
criteria = Criteria.where(findKeys[i]).is(findValues[i]);
} else {
criteria.and(findKeys[i]).is(findValues[i]);
}
}
Query query = Query.query(criteria);
Object resultObj = mongodbUtils.mongoTemplate.findOne(query, obj.getClass(), collectionName);
return resultObj;
}

/**
* 查询出所有结果集 集合为数据对象中 @Document 注解所配置的collection
*
* @param obj
* 数据对象
* @return
*/
public static List<? extends Object> findAll(Object obj) {

List<? extends Object> resultList = mongodbUtils.mongoTemplate.findAll(obj.getClass());
return resultList;
}

/**
* 查询出所有结果集 集合为数据对象中 @Document 注解所配置的collection
* @param clazz
* @param <T>
* @return
*/
public static <T> List<T> findAll(Class<T> clazz){
List<T> resultList = mongodbUtils.mongoTemplate.findAll(clazz);
return resultList;
}

/**
* 指定集合 查询出所有结果集
*
* @param obj
* 数据对象
* @param collectionName
* 集合名
* @return
*/
public static List<? extends Object> findAll(Object obj, String collectionName) {

List<? extends Object> resultList = mongodbUtils.mongoTemplate.findAll(obj.getClass(), collectionName);
return resultList;
}

/**
* 指定集合 查询出所有结果集
* @param clazz
* @param collectionName
* @param <T>
* @return
*/
public static <T> List<T> findAll(Class<T> clazz, String collectionName) {
List<T> resultList = mongodbUtils.mongoTemplate.findAll(clazz, collectionName);
return resultList;
}

}

测试

因为操作都差不多,我这里就测试两个好了,其他的今后使用的时候看注释好了。(其他相关操作的测试请看下方的链接处)

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
/**
* @author codekiller
* @date 2020/5/30 15:58
*/

@SpringBootTest(classes = MongodbtestSpringApplication.class)
@RunWith(SpringRunner.class)
public class TestMongodb {

@Test
public void testSave(){
Topic topic=new Topic();
topic.setName("从器件角度看,计算机经历了五代变化。但从系统结构看,至今绝大多数计算机仍属于( )计算机。");
topic.setType(1);
topic.setSubject(1266661195234037761L);

Map<Integer,String> select=new HashMap<>(16);
select.put(0,"并行");
select.put(1,"冯诺依曼");
select.put(2,"智能");
select.put(3,"串行");
topic.setSelect(select);

topic.setAnswer(1);
topic.setCreated(new Date());
topic.setDeleted(false);
topic.setNote("计算机组成原理");
MongodbUtils.save(topic);
}

@Test
public void testFind(){
List<Topic> all = MongodbUtils.findAll(Topic.class);
all.forEach((value)-> System.out.println(value));
}

实体类

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
/**
* @author codekiller
* @date 2020/5/30 16:02
*/
@Document(collection = "tb_topic")
@Data
public class Topic {

/**
* id
*/
@Id
private String id;

/**
* 名称
*/
private String name;

/**
* 选择题的选项
*/
private Map<Integer,String> select;

/**
* 答案
*/
private Integer answer;

/**
* 题目类型(0:选择题,1:判断题)
*/
private Integer type;

/**
* 题目的学科类型id
*/
private Long subject;

/**
* 备注信息
*/
private String note;

/**
* 相关的图片地址
*/
private String image;

/**
* 创建时间
*/
private Date created;

/**
* 逻辑删除
*/
private Boolean deleted;
}

新增结果

查询结果:

参考: https://blog.csdn.net/qq_37421862/article/details/81287247?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

-------------本文结束感谢您的阅读-------------
六经蕴籍胸中久,一剑十年磨在手

欢迎关注我的其它发布渠道