目录
- 环境准备
- 安装 Java Development Kit (JDK)
- 安装 MongoDB 数据库
- 安装 IDE (推荐 IntelliJ IDEA 或 VS Code)
- 创建 Maven/Gradle 项目
- 使用 Maven 创建项目
- 使用 Gradle 创建项目
- 配置 MongoDB Java Driver
- Maven 依赖 (
pom.xml) - Gradle 依赖 (
build.gradle)
- Maven 依赖 (
- 连接 MongoDB
- 基础连接代码
- 使用
MongoClient和MongoDatabase
- 核心操作:CRUD
- Create: 插入文档
- Read: 查询文档
- Update: 更新文档
- Delete: 删除文档
- 高级特性
- 分页查询 (
skip和limit) - 聚合查询 (
Aggregates) - 事务
- 分页查询 (
- 最佳实践与设计模式
- 使用
@Document注解映射 POJO - 使用
MongoTemplate(Spring Data MongoDB) - 异步操作
- 使用
- 完整示例代码
一个简单的命令行应用,包含所有 CRUD 操作。
(图片来源网络,侵删) - 进阶学习
环境准备
在开始之前,确保你的电脑上安装了以下软件:
- JDK: 版本 8 或更高,推荐使用 LTS (长期支持) 版本,如 JDK 11, 17, 或 21。
- 下载地址: Oracle JDK 或 OpenJDK
- MongoDB: 版本 4.4 或更高。
- 下载地址: MongoDB Download Center
- 安装后,确保 MongoDB 服务正在运行,默认端口是
27017。
- IDE:
- IntelliJ IDEA: 社区版免费,对 Java 和 Maven/Gradle 支持极佳。
- VS Code: 配合 Java 扩展包,也是一个轻量级的选择。
创建 Maven/Gradle 项目
这里以 Maven 为例,Gradle 的配置非常类似。
使用 Maven 创建项目
- 打开你的 IDE (如 IntelliJ IDEA)。
- 选择
New Project->Maven。 - 填写 GroupId (
com.example) 和 ArtifactId (java-mongo-demo)。 - 点击
Create。
IDE 会自动为你创建一个 pom.xml 文件。
使用 Gradle 创建项目
- 打开你的 IDE。
- 选择
New Project->Gradle->Java Application。 - 填写 GroupId 和 ArtifactId。
- 点击
Create。
IDE 会自动为你创建一个 build.gradle 文件。

配置 MongoDB Java Driver
你需要将官方的 MongoDB Java Driver 添加到你的项目依赖中。
Maven (pom.xml)
在 <dependencies> 标签内添加以下依赖:
<dependencies>
<!-- MongoDB Java Driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.11.1</version> <!-- 请使用最新版本 -->
</dependency>
<!-- 为了方便地操作 JSON 和 POJO,我们添加 bson 库 -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>4.11.1</version> <!-- 版本应与 driver 保持一致 -->
</dependency>
<!-- Lombok (可选,用于简化 Java 代码) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
</dependencies>
Gradle (build.gradle)
在 dependencies 代码块中添加:
dependencies {
// MongoDB Java Driver
implementation 'org.mongodb:mongodb-driver-sync:4.11.1' // 请使用最新版本
// Lombok (可选)
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}
连接 MongoDB
创建一个 MongoClient 实例来连接到你的 MongoDB 服务器。
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
public class MongoConnection {
public static void main(String[] args) {
// MongoDB 连接字符串
// MongoDB 运行在本机,使用默认端口,无需用户名密码
String uri = "mongodb://localhost:27017";
try (MongoClient mongoClient = MongoClients.create(uri)) {
// 连接到指定的数据库,如果数据库不存在,MongoDB 会在第一次插入数据时自动创建
MongoDatabase database = mongoClient.getDatabase("myDatabase");
System.out.println("成功连接到数据库: " + database.getName());
// 你可以在这里进行其他操作...
// 获取一个集合
// database.getCollection("users");
} catch (Exception e) {
System.err.println("连接 MongoDB 失败: " + e.getMessage());
e.printStackTrace();
}
}
}
说明:
MongoClients.create(uri): 创建一个客户端,使用try-with-resources语句可以确保客户端在使用完毕后被正确关闭。mongoClient.getDatabase("myDatabase"): 获取一个数据库对象。- 认证: 如果你的 MongoDB 启用了认证,连接字符串格式为
mongodb://username:password@host:port/。
核心操作:CRUD
假设我们要操作一个名为 users 的集合(Collection),集合的结构如下:
{
"name": "Alice",
"age": 30,
"email": "alice@example.com",
"city": "New York"
}
C - Create (插入文档)
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import org.bson.Document;
public class InsertExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 创建一个文档
Document user = new Document("name", "Bob")
.append("age", 25)
.append("email", "bob@example.com")
.append("city", "London");
// 插入单个文档
collection.insertOne(user);
System.out.println("文档插入成功!");
// 插入多个文档
Document user2 = new Document("name", "Charlie").append("age", 35);
collection.insertMany(List.of(user, user2)); // 注意: List.of 需要 Java 9+
System.out.println("多个文档插入成功!");
}
}
}
R - Read (查询文档)
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import com.mongodb.client.model.Filters;
import org.bson.Document;
public class FindExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 1. 查找所有文档
System.out.println("--- 所有用户 ---");
collection.find().forEach(doc -> System.out.println(doc.toJson()));
// 2. 查找 name 为 "Alice" 的文档
System.out.println("\n--- 名为 Alice 的用户 ---");
Document alice = collection.find(Filters.eq("name", "Alice")).first();
if (alice != null) {
System.out.println(alice.toJson());
}
// 3. 查找 age 大于 28 的所有用户
System.out.println("\n--- 年龄大于 28 的用户 ---");
MongoCursor<Document> cursor = collection.find(Filters.gt("age", 28)).iterator();
try {
while (cursor.hasNext()) {
System.out.println(cursor.next().toJson());
}
} finally {
cursor.close(); // 确保关闭游标
}
}
}
}
说明:
collection.find(): 返回一个FindIterable,可以链式调用查询条件。Filters: 提供了构建查询条件的静态方法,如eq(等于),gt(大于),lt(小于),in(在...之中) 等。
U - Update (更新文档)
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.bson.conversions.Bson;
public class UpdateExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 定义更新条件
Bson filter = Filters.eq("name", "Bob");
// 定义更新操作
Bson updateOperation = Updates.set("city", "Paris");
// 执行更新
UpdateResult result = collection.updateOne(filter, updateOperation);
System.out.println("匹配的文档数量: " + result.getMatchedCount());
System.out.println("修改的文档数量: " + result.getModifiedCount());
}
}
}
说明:
updateOne: 更新第一个匹配的文档。updateMany: 更新所有匹配的文档。Updates: 提供了构建更新操作的静态方法,如set,inc,unset等。
D - Delete (删除文档)
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import org.bson.Document;
public class DeleteExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 1. 删除 name 为 "Charlie" 的一个文档
Bson filter1 = Filters.eq("name", "Charlie");
DeleteResult result1 = collection.deleteOne(filter1);
System.out.println("删除的文档数量: " + result1.getDeletedCount());
// 2. 删除所有 age 小于 30 的文档
Bson filter2 = Filters.lt("age", 30);
DeleteResult result2 = collection.deleteMany(filter2);
System.out.println("删除的文档数量: " + result2.getDeletedCount());
}
}
}
高级特性
分页查询
使用 skip() 和 limit() 方法实现分页。
// 假设集合中有很多文档
// 获取第 2 页,每页 10 条数据 (跳过前 10 条,获取接下来的 10 条)
collection.find()
.skip(10) // 跳过的文档数
.limit(10) // 限制返回的文档数
.forEach(doc -> System.out.println(doc.toJson()));
聚合查询
聚合管道用于处理数据记录并返回计算结果,它非常强大,类似于 SQL 中的 GROUP BY, HAVING, JOIN 等。
场景: 统计每个城市的用户数量。
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import org.bson.Document;
public class AggregateExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// 构建聚合管道
// 第一阶段: 按 city 字段进行分组
// 第二阶段: 计算每个组的数量
List<Bson> pipeline = List.of(
new Document("$group", new Document("_id", "$city")
.append("userCount", new Document("$sum", 1))),
new Document("$sort", new Document("userCount", -1)) // 按数量降序排序
);
Aggregate<Document> aggregate = collection.aggregate(pipeline, Document.class);
System.out.println("--- 按城市统计用户数 ---");
aggregate.forEach(doc -> System.out.println(doc.toJson()));
}
}
}
事务
MongoDB 4.0+ 支持多文档事务,事务确保一组操作要么全部成功,要么全部失败。
重要: 事务必须在副本集或分片集群上运行,本地单节点 MongoDB 默认不支持事务。
import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClients;
import org.bson.Document;
public class TransactionExample {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017"; // 确保你的 MongoDB 是副本集模式
try (var mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
// 开始一个会话
try (ClientSession session = mongoClient.startSession()) {
session.startTransaction();
try {
MongoCollection<Document> collection1 = database.getCollection("accounts");
MongoCollection<Document> collection2 = database.getCollection("transactions");
// 操作1: 从账户 A 扣款
collection1.updateOne(session, Filters.eq("accountId", "A123"),
Updates.inc("balance", -100));
// 操作2: 向账户 B 存款
collection1.updateOne(session, Filters.eq("accountId", "B456"),
Updates.inc("balance", 100));
// 记录一笔交易
collection2.insertOne(session, new Document("from", "A123")
.append("to", "B456")
.append("amount", 100));
// 如果所有操作都成功,则提交事务
session.commitTransaction();
System.out.println("事务提交成功!");
} catch (Exception e) {
// 如果任何操作失败,则回滚事务
session.abortTransaction();
System.err.println("事务执行失败,已回滚: " + e.getMessage());
}
}
}
}
}
最佳实践与设计模式
直接使用 MongoCollection 和 Document 虽然灵活,但在大型项目中容易出错且难以维护,推荐使用更高级的抽象。
使用 @Document 注解映射 POJO
你可以创建一个 Java 类(POJO)来映射 MongoDB 的文档结构,这样代码更清晰、类型更安全。
import org.bson.types.ObjectId;
import lombok.Data; // Lombok 注解,自动生成 getter/setter
@Data
public class User {
@Id // 标记此字段为文档的主键 _id
private ObjectId id;
private String name;
private int age;
private String email;
private String city;
}
使用 MongoTemplate (Spring Data MongoDB)
如果你的项目是 Spring Boot 应用,强烈推荐使用 Spring Data MongoDB,它提供了 MongoTemplate,极大地简化了数据访问。
添加 Spring Boot 依赖:
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置 application.properties:
# src/main/resources/application.properties spring.data.mongodb.uri=mongodb://localhost:27017/myDatabase
创建 Repository 接口:
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface UserRepository extends MongoRepository<User, ObjectId> {
// Spring Data 会自动实现这些方法
List<User> findByName(String name);
List<User> findByAgeGreaterThan(int age);
}
在 Service 中使用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void createUser(User user) {
userRepository.save(user);
}
public List<User> findUsersByName(String name) {
return userRepository.findByName(name);
}
}
这种方式将你从底层的数据库操作中解放出来,让你可以专注于业务逻辑。
完整示例代码 (纯 Java Driver)
这是一个整合了所有 CRUD 操作的完整示例。
import com.mongodb.client.*;
import com.mongodb.client.model.*;
import org.bson.Document;
import org.bson.types.ObjectId;
import java.util.ArrayList;
import java.util.List;
public class MongoApp {
public static void main(String[] args) {
String uri = "mongodb://localhost:27017";
try (MongoClient mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("myDatabase");
MongoCollection<Document> collection = database.getCollection("users");
// --- 清空集合,方便测试 ---
collection.deleteMany(new Document());
// --- C: Create ---
System.out.println("--- 插入文档 ---");
List<Document> newUsers = new ArrayList<>();
newUsers.add(new Document("name", "Alice").append("age", 30).append("city", "New York"));
newUsers.add(new Document("name", "Bob").append("age", 25).append("city", "London"));
newUsers.add(new Document("name", "Charlie").append("age", 35).append("city", "New York"));
collection.insertMany(newUsers);
System.out.println("插入了 " + newUsers.size() + " 个文档。");
// --- R: Read ---
System.out.println("\n--- 查询所有文档 ---");
collection.find().forEach(doc -> System.out.println(doc.toJson()));
System.out.println("\n--- 查询年龄大于 28 的用户 ---");
collection.find(Filters.gt("age", 28))
.forEach(doc -> System.out.println(doc.toJson()));
// --- U: Update ---
System.out.println("\n--- 将 Bob 的城市更新为 Paris ---");
UpdateResult updateResult = collection.updateOne(
Filters.eq("name", "Bob"),
Updates.set("city", "Paris")
);
System.out.println("匹配了 " + updateResult.getMatchedCount() + " 个文档,修改了 " + updateResult.getModifiedCount() + " 个。");
// --- D: Delete ---
System.out.println("\n--- 删除 Charlie ---");
DeleteResult deleteResult = collection.deleteOne(Filters.eq("name", "Charlie"));
System.out.println("删除了 " + deleteResult.getDeletedCount() + " 个文档。");
System.out.println("\n--- 最终数据 ---");
collection.find().forEach(doc -> System.out.println(doc.toJson()));
}
}
}
进阶学习
当你掌握了基础后,可以继续探索以下内容:
- Spring Boot + MongoDB: 学习如何使用 Spring Boot 快速构建 RESTful API 与 MongoDB 交互。
- 异步驱动 (
mongodb-driver-reactive): 对于高并发应用,学习使用响应式编程模型 (如 Project Reactor 或 RxJava) 进行异步非阻塞操作。 - 索引: 学习如何创建索引来提高查询性能。
- 数据建模: 深入学习 MongoDB 的数据模型设计,如嵌入式文档和引用文档的优劣。
- GridFS: 用于存储和检索超过 16MB 的文件。
- 监控: 学习如何使用 MongoDB 的性能监控工具(如
mongotop,mongostat)和 MMS/Metricbeat。
希望这份详细的指南能帮助你顺利开启 Java 与 MongoDB 的项目开发之旅!
