1. 简介
本文将介绍 MongoDB 中的核心概念之一 —— BSON,以及如何使用 Java 驱动通过 BSON 与 MongoDB 进行交互。
虽然本文不会深入讲解 MongoDB 的全部功能,但我们会介绍一些关键概念。MongoDB 是一个分布式的 NoSQL 文档存储引擎,文档以 BSON 格式存储,并组织在集合中。集合中的文档类似于关系型数据库中的行。
如果你对 MongoDB 的整体架构和使用方式感兴趣,可以参考我们之前的 MongoDB 入门教程。
2. 什么是 BSON?
BSON 是 Binary JSON 的缩写,是一种用于序列化 JSON 类型数据的二进制协议。
JSON 是现代 Web 服务中广泛使用的数据交换格式,它提供了一种灵活的方式来表示复杂的数据结构。相比 JSON,BSON 提供了以下优势:
✅ 更紧凑:在大多数情况下,BSON 比等效的 JSON 占用更少的存储空间
✅ 支持更多数据类型:如 Date
、BinData
等 JSON 不支持的类型
✅ 易于遍历:BSON 文档中包含额外的元信息,便于直接定位和修改字段,而无需解析整个文档
这些特性使得 BSON 成为 MongoDB 的理想存储格式。
3. MongoDB Java 驱动
我们已经了解了 BSON 的基本概念,现在来看看如何使用 MongoDB Java 驱动通过 BSON 进行 CRUD 操作(即 Create、Read、Update、Delete)。
MongoDB 提供了多种语言的官方驱动,这些驱动都基于 BSON 库构建,因此我们使用驱动时,本质上就是在操作 BSON 数据结构。
⚠️ 本文主要介绍直接使用 BSON API 的方式。如果你希望使用更高级的封装,比如 Spring Data MongoDB,可以参考我们的 Spring Data MongoDB 教程
3.1. 建立连接
首先,添加 MongoDB Java 驱动依赖:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.8.2</version>
</dependency>
然后使用 Java 代码连接数据库和集合:
MongoClient mongoClient = MongoClients.create();
MongoDatabase database = mongoClient.getDatabase("myDB");
MongoCollection<Document> collection = database.getCollection("employees");
接下来我们将使用 collection
引用进行各种操作。
3.2. 插入文档
假设我们要插入如下 JSON 数据到 employees
集合中:
{
"first_name" : "Joe",
"last_name" : "Smith",
"title" : "Java Developer",
"years_of_service" : 3,
"skills" : ["java","spring","mongodb"],
"manager" : {
"first_name" : "Sally",
"last_name" : "Johanson"
}
}
使用 Java 的 Document
类可以轻松构建 BSON 文档并插入:
Document employee = new Document()
.append("first_name", "Joe")
.append("last_name", "Smith")
.append("title", "Java Developer")
.append("years_of_service", 3)
.append("skills", Arrays.asList("java", "spring", "mongodb"))
.append("manager", new Document()
.append("first_name", "Sally")
.append("last_name", "Johanson"));
collection.insertOne(employee);
Document
类继承自 Java 的 Map
接口,支持丰富的类型操作,包括嵌套文档、数组等。
3.3. 查询文档
MongoDB 查询文档通过构建一个“查询条件”文档来实现。例如,查找所有姓氏为 "Smith" 的员工:
{
"last_name": "Smith"
}
对应的 Java 代码如下:
Document query = new Document("last_name", "Smith");
List<Document> results = new ArrayList<>();
collection.find(query).into(results);
默认情况下,多个查询条件之间是 AND
关系,即必须全部匹配。若想使用 OR
查询,可以这样写:
{
"$or": [
{ "first_name": "Joe" },
{ "last_name":"Smith" }
]
}
对应的 Java 代码如下:
Document query = new Document("$or", Arrays.asList(
new Document("last_name", "Smith"),
new Document("first_name", "Joe")));
List<Document> results = new ArrayList<>();
collection.find(query).into(results);
3.4. 更新文档
MongoDB 的更新操作需要两个文档:
- 查询条件文档
- 更新操作文档
例如,给所有拥有 "spring" 技能的员工添加一个新的 "security" 技能:
对应的 JSON 查询条件和更新操作如下:
{
"skills": {
"$elemMatch": {
"$eq": "spring"
}
}
}
{
"$push": {
"skills": "security"
}
}
对应的 Java 代码:
Document query = new Document(
"skills",
new Document(
"$elemMatch",
new Document("$eq", "spring")));
Document update = new Document(
"$push",
new Document("skills", "security"));
collection.updateMany(query, update);
3.5. 删除文档
删除文档的语法与查询类似,只需要传入匹配条件即可。
例如,删除 years_of_service
为负数的员工:
{
"years_of_service" : {
"$lt" : 0
}
}
对应的 Java 代码如下:
Document query = new Document(
"years_of_service",
new Document("$lt", 0));
collection.deleteMany(query);
4. 总结
本文我们介绍了如何使用 MongoDB 的 Java 驱动和 BSON API 实现基本的 CRUD 操作。通过 Document
类,我们可以灵活地构建和操作 BSON 数据结构。
虽然本文没有涉及投影(Projection)、聚合(Aggregation)、地理空间查询等高级特性,但这些功能都可以通过 BSON API 实现。掌握本文中的基础操作,是实现这些高级功能的前提。
完整示例代码可以在我们的 GitHub 仓库 中找到。