Java SDK

最近更新时间:2026-05-07 11:54:32

我的收藏

操作场景

Java 是企业级应用开发的主流语言,MongoDB 官方 Java Driver 提供了同步和异步两种 API,并与 Spring Data MongoDB 深度集成。本文提供使用 Java 驱动连接云数据库 MongoDB 的完整示例,覆盖原生驱动和 Spring Boot 两种接入方式。

前提条件

已创建云数据库 MongoDB 实例,且实例状态为运行中
已准备一台与 MongoDB 实例在同一 VPC 内的云服务器 CVM,且已安装 JDK 8 或以上版本。
开发环境已配置 Maven 或 Gradle 构建工具。

驱动版本

说明:
旧版 mongo-java-driver(3.x)已停止维护,请迁移至 4.x 版本。
驱动
推荐版本
兼容 MongoDB 版本
说明
mongodb-driver-sync
4.9或以上
4.0 - 8.0
官方同步驱动,适用于传统阻塞式编程
mongodb-driver-reactivestreams
4.9或以上
4.0 - 8.0
官方响应式驱动,适用于异步非阻塞场景

注意事项

认证库配置:无论使用原生驱动还是 Spring Data MongoDB,都必须指定认证库为 admin
连接池管理:生产环境中,MongoClient 实例应全局复用(单例模式),避免每次操作都创建新的连接。
资源释放:使用完毕后,务必关闭 MongoClient。推荐使用 try-with-resources 语法自动关闭。
异常处理:生产代码中应捕获 MongoException 及其子类,并进行相应的重试或告警处理。

添加依赖

Maven(pom.xml):
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.11.1</version>
</dependency>
Gradle(build.gradle):
implementation 'org.mongodb:mongodb-driver-sync:4.11.1'

方式一:原生 Java Driver 连接

以下示例演示使用 MongoDB Java Driver 连接云数据库 MongoDB,完成文档插入和查询操作。
package com.example.mongodb;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import org.bson.Document;

import java.util.concurrent.TimeUnit;

public class MongoDBDemo {

public static void main(String[] args) {
// 连接 URI(请替换为您的实际连接信息)
// 副本集连接串格式:
// mongodb://mongouser:<password>@<IP1>:27017,<IP2>:27017,<IP3>:27017/admin?replicaSet=cmgo-xxxxxxxx_0
String uri = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/admin";

// 配置连接参数(包含连接池设置)
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(uri))
.applyToConnectionPoolSettings(builder -> builder
.maxSize(50) // 连接池上限
.minSize(5) // 连接池下限
.maxWaitTime(5, TimeUnit.SECONDS) // 等待可用连接的超时时间
.maxConnectionIdleTime(60, TimeUnit.SECONDS)) // 空闲连接超时
.applyToSocketSettings(builder -> builder
.connectTimeout(10, TimeUnit.SECONDS) // 连接超时
.readTimeout(30, TimeUnit.SECONDS)) // 读取超时
.retryWrites(true) // 启用可重试写入
.retryReads(true) // 启用可重试读取
.build();

// 创建客户端连接(使用 try-with-resources 自动关闭)
try (MongoClient mongoClient = MongoClients.create(settings)) {
// 选择数据库
MongoDatabase database = mongoClient.getDatabase("mydb");

// 获取集合
MongoCollection<Document> collection = database.getCollection("users");

// 插入文档
Document doc = new Document("username", "jack")
.append("age", 31)
.append("email", "jack@example.com");
collection.insertOne(doc);
System.out.println("插入文档: " + doc.toJson());

// 查询文档
Document result = collection.find(Filters.eq("username", "jack")).first();
if (result != null) {
System.out.println("查询结果: " + result.toJson());
}

// 更新文档
collection.updateOne(
Filters.eq("username", "jack"),
new Document("$set", new Document("age", 32))
);
System.out.println("更新完成");

// 删除文档
collection.deleteOne(Filters.eq("username", "jack"));
System.out.println("删除完成");

} catch (Exception e) {
System.err.println("数据库操作失败: " + e.getMessage());
e.printStackTrace();
}
}
}
运行输出示例:
插入文档: {"username": "jack", "age": 31, "email": "jack@example.com", "_id": {"$oid": "6789abcdef1234567890abcd"}}
查询结果: {"_id": {"$oid": "6789abcdef1234567890abcd"}, "username": "jack", "age": 31, "email": "jack@example.com"}
更新完成
删除完成

方式二:Spring Boot 集成

Spring Boot 通过 Spring Data MongoDB 提供了声明式的数据库操作支持,简化了开发流程。

添加依赖

Maven(pom.xml):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置连接信息

application.yml:
spring:
data:
mongodb:
uri: mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb?authSource=admin
# 副本集连接串:
# uri: mongodb://mongouser:thepasswordA1@IP1:27017,IP2:27017,IP3:27017/mydb?authSource=admin&replicaSet=cmgo-xxxxxxxx_0
说明:
authSource=admin 是必须的配置项,云数据库 MongoDB 统一使用 admin 库作为认证数据库。URI 中 /mydb 为业务数据库名称,与认证库 admin 是不同的概念。

定义实体类

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "users")
public class User {
@Id
private String id;
private String username;
private Integer age;
private String email;

// 构造函数、getter 和 setter 省略
}

定义 Repository

import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository<User, String> {
User findByUsername(String username);
}

使用示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MongoDBRunner implements CommandLineRunner {

@Autowired
private UserRepository userRepository;

@Override
public void run(String... args) {
// 插入文档
User user = new User();
user.setUsername("jack");
user.setAge(31);
user.setEmail("jack@example.com");
userRepository.save(user);

// 查询文档
User found = userRepository.findByUsername("jack");
System.out.println("查询结果: " + found);
}
}

常见问题

连接时抛出 "MongoSecurityException: Authentication failed"

异常堆栈示例:
com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='mongouser', source='admin', ...}
Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed)
请按以下步骤排查:
1. 确认 URI 中指定了认证库 admin:云数据库 MongoDB 的所有用户统一使用 admin 作为认证库。请确认 URI 格式正确:
// 正确:URI 路径指向 admin
String uri1 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/admin";
// 正确:连接业务库时通过 authSource 指定认证库
String uri2 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb?authSource=admin";

// 错误:连接业务库时未指定 authSource,驱动将默认以 mydb 库认证,导致认证失败
String uri3 = "mongodb://mongouser:thepasswordA1@10.66.187.127:27017/mydb";
2. 确认密码中的特殊字符已进行 URL 编码:如密码包含 @: 等特殊字符,需在 URI 中进行编码:
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

String password = URLEncoder.encode("pass@123", StandardCharsets.UTF_8);
String uri = String.format("mongodb://mongouser:%s@10.66.187.127:27017/admin", password);
3. 确认用户名和密码正确:登录 MongoDB 控制台,在实例管理页面确认用户名信息。如忘记密码,可在控制台重置。

连接时抛出 "MongoTimeoutException: Timed out while waiting to connect"

异常信息示例:
com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[...]
请按以下步骤排查:
1. 确认网络连通性:在 CVM 上执行以下命令,验证到 MongoDB 实例的网络是否可达:
telnet <MongoDB实例IP> 27017
输出 Connected 表示网络可达。
输出 Connection timed out 表示网络不通,请确认 CVM 与 MongoDB 实例在同一 VPC 内,并检查安全组规则。
2. 检查连接超时配置:确认 connectTimeoutMS 配置值合理。内网环境下,10秒(10000ms)足够:
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(uri))
.applyToSocketSettings(builder -> builder
.connectTimeout(10, TimeUnit.SECONDS))
.build();
3. 步骤三:确认副本集名称正确:如使用副本集连接串,请确认 replicaSet 参数值与控制台实例详情页显示的副本集名称一致:
mongodb://mongouser:thepasswordA1@IP1:27017,IP2:27017/admin?replicaSet=cmgo-xxxxxxxx_0
说明:
副本集名称通常为 cmgo-xxxxxxxx_0 格式,可在控制台实例详情页获取。

运行一段时间后出现 "MongoSocketReadException: Prematurely reached end of stream"

异常信息示例:
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
该异常通常由空闲连接被服务端主动断开引起。请检查连接池的空闲超时配置:
MongoClientSettings settings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(uri))
.applyToConnectionPoolSettings(builder -> builder
.maxConnectionIdleTime(60, TimeUnit.SECONDS)) // 空闲连接 60 秒后自动关闭
.build();
说明:
建议将 maxConnectionIdleTime 设置为60秒,避免长时间空闲的连接被服务端断开后仍被客户端复用。同时确保已开启 retryWrites(true)retryReads(true),驱动会自动重试因连接断开而失败的操作。