MongoDB初学者教程:从零开始掌握MongoDB(第二阶段:CRUD基础操作)
欢迎回到MongoDB的学习之旅!在第一阶段,我们了解了MongoDB的基本概念(NoSQL、文档型数据库、BSON格式),并完成了环境搭建和Java项目初始化。现在,我们进入第二阶段:CRUD基础操作,这是MongoDB的核心技能——如何在数据库中增删改查数据。
CRUD是什么?它代表:
- Create(创建):向数据库添加新数据。
- Read(读取):从数据库查询数据。
- Update(更新):修改数据库中的数据。
- Delete(删除):删除数据库中的数据。
本阶段将带你掌握MongoDB的文档操作(插入、查询、更新、删除),并通过Java驱动实现这些操作。你将学会用代码和MongoDB“对话”,像管理一个智能文件夹一样管理数据。本阶段约4000字,包含大量示例代码和实践步骤,适合零基础的你!
第二阶段:CRUD基础操作
一、基础文档操作
MongoDB的核心是文档(Document),类似于JSON格式的数据。文档存储在集合(Collection)中,集合就像一个文件夹,文档就像文件夹里的文件。我们的任务是用MongoDB的命令或Java代码,在这些“文件夹”里增删改查“文件”。
我们将使用MongoDB的命令行工具(mongosh
)或MongoDB Compass来演示操作,同时结合Java代码实现。假设你已经安装了MongoDB社区版(参考第一阶段),并且有一个名为mydb
的数据库,里面有一个users
集合。
1. 插入文档(insertOne/insertMany)
插入文档就是往集合里添加新数据,就像往文件夹里放一张新便签。
用MongoDB命令插入
在mongosh
中,连接到MongoDB(运行mongosh
),切换到mydb
数据库:
use mydb
插入单个文档(insertOne) :
db.users.insertOne({
"name": "小明",
"age": 20,
"city": "北京"
})
输出会显示插入成功的提示,包含文档的_id
(MongoDB自动生成的主键):
{
"acknowledged": true,
"insertedId": ObjectId("671234567890123456789012")
}
插入多个文档(insertMany) :
db.users.insertMany([ { "name": "小红", "age": 22, "city": "上海" }, { "name": "小刚", "age": 25, "city": "广州", "hobbies": ["读书", "旅行"]
}
])
输出会显示多个_id
:
{
"acknowledged": true,
"insertedIds": {
"0": ObjectId("671234567890123456789013"),
"1": ObjectId("671234567890123456789014")
}
}
用Compass插入
在MongoDB Compass中:
- 打开
mydb
数据库,点击users
集合。 - 点击“Add Data” -> “Insert Document”。
- 输入JSON格式的文档(比如
{"name": "小明", "age": 20}
),点击“Insert”。 - 刷新集合,查看新插入的数据。
生活化比喻:insertOne
就像往文件夹里放一张便签,insertMany
是把一叠便签一次性塞进去。MongoDB会自动给每张便签贴上一个唯一标签(_id
)。
2. 查询文档(find/findOne)
查询文档是从集合中查找数据,就像在文件夹里翻找特定便签。
用MongoDB命令查询
查询单个文档(findOne) :
db.users.findOne({"name": "小明"})
输出:
{
"_id": ObjectId("671234567890123456789012"),
"name": "小明",
"age": 20,
"city": "北京"
}
查询多个文档(find) :
db.users.find({"city": "上海"})
输出(可能有多条):
{
"_id": ObjectId("671234567890123456789013"),
"name": "小红",
"age": 22,
"city": "上海"
}
用find()
时,可以加.pretty()
让输出更美观:
db.users.find().pretty()
查询条件:
- 精确匹配:
{"age": 20}
- 范围查询:
{"age": {"$gt": 20}}
(大于20) - 数组包含:
{"hobbies": "读书"}
用Compass查询
- 在
users
集合界面,点击“Filter”栏。 - 输入查询条件(比如
{"name": "小明"}
),点击“Find”。 - 查看匹配的文档。
生活化比喻:findOne
是在文件夹里找到第一张写着“小明”的便签就停下来;find
是把所有符合条件的便签都拿出来。
3. 更新文档(updateOne/updateMany)
更新文档是修改集合中的数据,就像在便签上改写内容。
用MongoDB命令更新
更新单个文档(updateOne) :
把小明的年龄改为21:
db.users.updateOne(
{"name": "小明"},
{"$set": {"age": 21}}
)
输出:
{
"acknowledged": true,
"matchedCount": 1,
"modifiedCount": 1
}
{"name": "小明"}
:匹配条件。{"$set": {"age": 21}}
:更新操作,$set
表示修改字段。
更新多个文档(updateMany) :
把所有年龄大于20的用户城市改为“深圳”:
db.users.updateMany(
{"age": {"$gt": 20}},
{"$set": {"city": "深圳"}}
)
输出:
{
"acknowledged": true,
"matchedCount": 2,
"modifiedCount": 2
}
用Compass更新
- 在
users
集合中找到目标文档。 - 点击“Edit Document”,修改字段(比如把
age
改为21)。 - 点击“Update”保存。
生活化比喻:updateOne
是改一张便签的内容,updateMany
是把一堆符合条件的便签都改一遍。
4. 删除文档(deleteOne/deleteMany)
删除文档是从集合中移除数据,就像扔掉不需要的便签。
用MongoDB命令删除
删除单个文档(deleteOne) :
删除小明的文档:
db.users.deleteOne({"name": "小明"})
输出:
{
"acknowledged": true,
"deletedCount": 1
}
删除多个文档(deleteMany) :
删除所有城市为“深圳”的用户:
db.users.deleteMany({"city": "深圳"})
输出:
{
"acknowledged": true,
"deletedCount": 2
}
用Compass删除
- 在
users
集合中找到目标文档。 - 点击“Delete Document”(垃圾桶图标),确认删除。
生活化比喻:deleteOne
是扔掉一张便签,deleteMany
是把一堆符合条件的便签都扔掉。
二、Java驱动基础使用
现在,我们将用Java代码实现上述CRUD操作,基于第一阶段创建的Maven项目(包含MongoDB Java驱动)。我们会学习如何连接MongoDB、操作集合,以及将Java对象(POJO)与MongoDB文档相互转换。
1. MongoClient连接配置
在第一阶段,我们用以下代码连接了MongoDB:
MongoClient client = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = client.getDatabase("mydb");
为了更灵活,我们可以配置连接参数,比如超时时间、连接池大小。以下是一个更完整的连接示例:
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
public class MongoDBConnection {
public static MongoClient connect() {
ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017");
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(settings);
}
}
保存这个类,之后可以重复使用connect()
方法获取MongoClient
。
2. 使用MongoCollection进行CRUD
我们将用MongoCollection
操作users
集合,实现CRUD。以下是完整示例代码。
准备工作:
创建一个Java类UserCRUDSample
,包含所有CRUD操作:
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class UserCRUDSample {
private final MongoCollection<Document> users;
public UserCRUDSample(MongoClient client) {
MongoDatabase database = client.getDatabase("mydb");
users = database.getCollection("users");
}
}
插入文档:
public void insertUser() {
// 插入单个文档
Document user1 = new Document("name", "小明")
.append("age", 20)
.append("city", "北京");
users.insertOne(user1);
System.out.println("Inserted user: 小明");
// 插入多个文档
List<Document> userList = Arrays.asList(
new Document("name", "小红").append("age", 22).append("city", "上海"),
new Document("name", "小刚").append("age", 25).append("city", "广州")
.append("hobbies", Arrays.asList("读书", "旅行"))
);
users.insertMany(userList);
System.out.println("Inserted multiple users");
}
查询文档:
public void findUsers() {
// 查询单个文档
Document user = users.find(new Document("name", "小明")).first();
System.out.println("Found user: " + user.toJson());
// 查询多个文档
FindIterable<Document> results = users.find(new Document("city", "上海"));
for (Document doc : results) {
System.out.println("Found user in 上海: " + doc.toJson());
}
}
更新文档:
public void updateUsers() {
// 更新单个文档
users.updateOne(
new Document("name", "小明"),
new Document("$set", new Document("age", 21))
);
System.out.println("Updated 小明's age");
// 更新多个文档
users.updateMany(
new Document("age", new Document("$gt", 20)),
new Document("$set", new Document("city", "深圳"))
);
System.out.println("Updated users' city to 深圳");
}
删除文档:
public void deleteUsers() {
// 删除单个文档
users.deleteOne(new Document("name", "小明"));
System.out.println("Deleted 小明");
// 删除多个文档
users.deleteMany(new Document("city", "深圳"));
System.out.println("Deleted users in 深圳");
}
主程序:
public static void main(String[] args) {
MongoClient client = MongoDBConnection.connect();
UserCRUDSample crud = new UserCRUDSample(client);
crud.insertUser();
crud.findUsers();
crud.updateUsers();
crud.deleteUsers();
client.close();
}
运行这个程序,你会看到MongoDB的CRUD操作结果。确保MongoDB服务(mongod
)已启动。
3. POJO与Document转换
在实际开发中,我们通常用Java对象(POJO,Plain Old Java Object)表示数据,而不是直接操作Document
。MongoDB Java驱动支持POJO与文档的转换。
定义POJO:
创建一个User
类:
public class User {
private String id;
private String name;
private int age;
private String city;
private List<String> hobbies;
// 构造函数
public User(String name, int age, String city) {
this.name = name;
this.age = age;
this.city = city;
}
// Getter和Setter
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public List<String> getHobbies() { return hobbies; }
public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; }
}
使用POJO操作:
MongoDB驱动需要Codec
来转换POJO和文档。我们可以用MongoCollection<User>
直接操作User
对象:
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
public class UserPOJOSample {
private final MongoCollection<User> users;
public UserPOJOSample(MongoClient client) {
CodecRegistry pojoCodecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(PojoCodecProvider.builder().automatic(true).build())
);
MongoDatabase database = client.getDatabase("mydb").withCodecRegistry(pojoCodecRegistry);
users = database.getCollection("users", User.class);
}
public void insertUser() {
User user = new User("小明", 20, "北京");
users.insertOne(user);
System.out.println("Inserted POJO user: 小明");
}
public void findUser() {
User user = users.find(Filters.eq("name", "小明")).first();
System.out.println("Found POJO user: " + user.getName() + ", " + user.getAge());
}
public void updateUser() {
users.updateOne(
Filters.eq("name", "小明"),
Updates.set("age", 21)
);
System.out.println("Updated POJO user's age");
}
public void deleteUser() {
users.deleteOne(Filters.eq("name", "小明"));
System.out.println("Deleted POJO user");
}
public static void main(String[] args) {
MongoClient client = MongoDBConnection.connect();
UserPOJOSample pojoSample = new UserPOJOSample(client);
pojoSample.insertUser();
pojoSample.findUser();
pojoSample.updateUser();
pojoSample.deleteUser();
client.close();
}
}
说明:
PojoCodecProvider
自动将User
对象与MongoDB文档映射。Filters
和Updates
提供了更简洁的查询和更新语法。- POJO让代码更符合面向对象编程习惯,适合复杂项目。
下一步是什么?
恭喜你掌握了MongoDB的CRUD操作!你学会了用命令和Java代码插入、查询、更新、删除文档,还能用POJO优雅地操作数据。这些技能是MongoDB开发的基础,就像学会了管理一个智能文件夹的“增删改查”。
后续阶段我们将深入:
- 第三阶段:Java开发实践(Spring Boot集成、REST API实现,约4000字)
- 第四阶段:进阶与优化(索引、聚合、分布式部署,约4000字)
- 第五阶段:实战项目(开发一个完整的Web应用,约5000字)
这些阶段将基于本阶段的代码,逐步构建一个真实项目。继续加油,你离成为MongoDB高手又近了一步!