本文使用 Java 来描述对 Mongodb 的相关操作,数据库版本是 3.2.8,驱动版本为 3.2.2。
本文将讨论
- 如何连接MongoDB
- 文档的 CURD 操作
- 文档的上传和下载
1. 连接到MongoDB
首先保证 mongodb 启动了身份验证功能(不启动直接使用IP,Port连接即可)。连接目标可分为三种:单机,集群和副本集。
1.1 连接单机和集群
站在代码的角度,单机和集群的区别就是端口号不同,假设服务器地址和端口号为:192.168.0.8和27017,则连接代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
String user =
"admin"
;
String pwd =
"111111"
;
String authDb =
"admin"
;
String host =
"192.168.0.8"
;
int
port =
27017
;
// 1. 直接连接
MongoCredential credential = MongoCredential.createCredential(user, authDb, pwd.toCharArray());
MongoClient mongoClient =
new
MongoClient(
new
ServerAddress(host , port), Arrays.asList(credential));
// 2. 使用连接字符串连接
MongoClientURI uri =
new
MongoClientURI(MessageFormat.format(conString, user, pwd, host, port+
""
, authDb));
//注意port为字符串
MongoClient mongoClient =
new
MongoClient(uri);
|
1.2 连接副本集
1
2
3
4
5
6
7
8
9
10
11
|
// 1. 直接连接
MongoClient mongoCli1ent =
new
MongoClient(
Arrays.asList(
new
ServerAddress(
"localhost"
,
27017
),
new
ServerAddress(
"localhost"
,
27018
)),
Arrays.asList(MongoCredential.createCredential(user, authDb, pwd.toCharArray())));
// 2. 使用连接字符串
// mongodb://user:pwd@host:port, host:port/?authSource=db&replicaSet=rs&slaveOk=true
MongoClientURI uri=
new
MongoClientURI(MessageFormat.format(conStr,
"admin"
,
"111"
,
"host1"
,
"27017"
,
"host2"
,
"27018"
,
"admin"
,
"rs0"
));
MongoClient mongoClient =
new
MongoClient(uri);
|
1.3 关于连接相关的参数
不管是使用字符串连接,还是直接连接都可以附带一些参数,直接连接时用 MongoClientOptions 类的builder()构造,字符串直接使用 & 拼接在后面就行。常用的参数如下:
replicaSet=name | 副本集名称 | ssl=true|false | 是否使用ssl |
connectTimeoutMS=ms | 连接超时时间 | socketTimeoutMS=ms | socket超时时间 |
maxPoolSize=n | 连接池大小 | safe=true|false | 驱动是否发送getLastError |
journal=true|false | 是否等待将日志刷到磁盘 | ||
authMechanism= | 身份验证方式 | 验证方式有SCRAM-SHA-1 | MONGODB-X509,MONGO-CR,etc |
authSource=string | 验证数据库,默认admin | 采用指定数据库的验证方式 | 3.0之后,默认验证方式为 SCRAM-SHA-1. |
更多详细的参数请见:MongoClientURI
2. 文档的 CURD 操作
在进行 CURD 操作时,有几个常用的辅助静态类:Filters, Sorts, Projections,Updates,详细用法请查看:Builders
(1)文档的插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 获取待插入集合 mycol
MongoDatabase mydb = mongoClient.getDatabase(
"myDb"
);
MongoCollection<Document> mycol = mydb.getCollection(
"myCol"
);
// 生成一个文档
Document doc =
new
Document();
doc.put(
"name"
,
"cyhe"
);
// 也可以使用链式风格构建
new
Document(
"id"
,
1
).append(
"name"
,
"cyhe"
);
// ... etc
// 也可以直接将 JSON 转成 BSON
// 插入
mycol.insertOne(doc);
// 批量插入
mycol.insertMany(
new
ArrayList<Document>());
|
(2)文档的查找
1
2
3
4
5
6
7
|
// 查询集合所有文档
List<Document> docs = mycol.find().into(
new
ArrayList<Document>());
// 直接导入 import static com.mongodb.client.model.Filters.*; 就可以直接使用 and eq 等静态方法
// 查询 age = 20 的文档
Document doc = mycol.find(Filters.eq(
"age"
,
20
)).first();
// 查询 10<age<20 的文档 返回一个游标
MongoCursor<Document> cur=mycol.find(Filters.and(Filters.gt(
"age"
,
10
), Filters.lt(
"age"
,
20
))).iterator();
|
(3)文档的更新和删除
1
2
3
4
5
6
7
8
|
// 查找并删除名称为 cyhe 的文档
mycol.findOneAndDelete(Filters.eq(
"name"
,
"cyhe"
));
// 查找并重命名
mycol.findOneAndUpdate(Filters.eq(
"name"
,
"cyhe"
), Updates.set(
"name"
,
"wqq"
));
// 小于10的都加1
mycol.updateMany(Filters.lt(
"size"
,
10
), Updates.inc(
"size"
,
1
));
// 删除 age 大于 110 的文档
mycol.deleteOne(Filters.gt(
"age"
,
"110"
));
|
3. 文档的上传和下载
在Mongodb中,普通文档最大为16M,对于图片,附件来说就显得比较小了,mongodb的处理方式就是使用 GridFS 分块存储。
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
|
// GridFS 默认的名字为 fs,使用默认名称连接
GridFSBucket gridFSBucket = GridFSBuckets.create(mydb);
// 使用指定名称连接
GridFSBucket gridFSBucket1 = GridFSBuckets.create(mydb,
"imags"
);
// 上传文件
// ==============================================================================================
InputStream streamToUploadFrom =
new
FileInputStream(
new
File(
"/tmp/mongodb-tutorial.pdf"
));
// 自定义参数
GridFSUploadOptions options =
new
GridFSUploadOptions()
.chunkSizeBytes(
1024
)
.metadata(
new
Document(
"type"
,
"presentation"
));
ObjectId fileId = gridFSBucket.uploadFromStream(
"mongodb-tutorial"
, streamToUploadFrom, options);
// ===============================================================================================
// 或者使用 GridFSUploadStream
byte
[] data =
"Data to upload into GridFS"
.getBytes(StandardCharsets.UTF_8);
GridFSUploadStream uploadStream = gridFSBucket.openUploadStream(
"sampleData"
, options);
uploadStream.write(data);
uploadStream.close();
System.out.println(
"The fileId of the uploaded file is: "
+ uploadStream.getFileId().toHexString());
// ===============================================================================================
// 下载文件
// ===============================================================================================
// 根据生成的 ObjectId 下载
FileOutputStream streamToDownloadTo =
new
FileOutputStream(
"/tmp/mongodb-tutorial.pdf"
);
gridFSBucket.downloadToStream(fileId, streamToDownloadTo);
streamToDownloadTo.close();
System.out.println(streamToDownloadTo.toString());
// ===============================================================================================
// 根据文件名称下载
FileOutputStream streamToDownloadTo =
new
FileOutputStream(
"/tmp/mongodb-tutorial.pdf"
);
GridFSDownloadByNameOptions downloadOptions =
new
GridFSDownloadByNameOptions().revision(
0
);
gridFSBucket.downloadToStreamByName(
"mongodb-tutorial"
, streamToDownloadTo, downloadOptions);
streamToDownloadTo.close();
// ===============================================================================================
// 使用 GridFSDownloadStream 根据 ObjectId 下载
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStream(fileId);
int
fileLength = (
int
) downloadStream.getGridFSFile().getLength();
byte
[] bytesToWriteTo =
new
byte
[fileLength];
downloadStream.read(bytesToWriteTo);
downloadStream.close();
System.out.println(
new
String(bytesToWriteTo, StandardCharsets.UTF_8));
// ===============================================================================================
// 使用 GridFSDownloadStream 根据 名称 下载
GridFSDownloadStream downloadStream = gridFSBucket.openDownloadStreamByName(
"sampleData"
);
int
fileLength = (
int
) downloadStream.getGridFSFile().getLength();
byte
[] bytesToWriteTo =
new
byte
[fileLength];
downloadStream.read(bytesToWriteTo);
downloadStream.close();
System.out.println(
new
String(bytesToWriteTo, StandardCharsets.UTF_8));
|
本文只是 Mongodb 操作的冰山一角,更多的用法,会在以后的实战中不断更新完善。更多用法和 API 介绍,详见 MongoDB-Java-3.2