ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MongoDB 3.0 for Java 学习记录(一、Java 连接 MongoDB 的配置与验证)

MongoDB 3.0 for Java 学习记录(一、Java 连接 MongoDB 的配置与验证) 1. 为什么第一次用 Java 连 MongoDB 3.0 容易卡住MongoDB 3.0 这个版本在 Java 生态里有点特殊。它正好处在驱动从 2.x 向 3.x 过渡的阶段网上搜到的示例代码经常混着两代 API有的用MongoClientURI直接塞连接串有的用ServerAddressMongoCredential手动拼认证信息。你如果照着某篇博客抄很可能遇到「编译能过、运行报错」或者「连上了但读不到数据」的情况。这篇要解决的就是这个场景你本地或者测试机上跑着一个 MongoDB 3.0 实例现在想用 Java 项目连上去完成一次真实的 insert 和 find确认链路是通的。适合刚接触 MongoDB 的 Java 后端、需要给老项目补连接配置的同学以及想搞清楚「认证模式和非认证模式到底差在哪」的开发者。核心检索词先摆出来Java 连接 MongoDB 3.0 的配置与验证重点在 Maven 依赖坐标、MongoClient 构造参数、连接超时设置、SCRAM-SHA-1 认证以及用一次写入加查询来验证连接是否真正可用。这几个点串起来就是一条完整的首次接入链路。我试过在同一个项目里同时保留两种连接方式结果发现最容易出问题的不是代码本身而是依赖版本和认证机制的匹配。MongoDB 3.0 默认的认证插件是 SCRAM-SHA-1而驱动版本如果选错createScramSha1Credential这个方法可能根本不存在。所以下面会先把依赖锁死再谈连接。另外提醒一句MongoDB 3.0 属于比较老的版本生产环境建议评估升级。但很多遗留系统还在用学习记录的价值就在于把这条老链路走通后面迁移时心里有底。2. 接入前的准备Maven 依赖与 TaoToken 配置入口在写 Java 代码之前先把两件事定下来驱动依赖的坐标以及如果你需要调用大模型辅助排查报错时的配置入口。先说 Maven。MongoDB 3.0 对应的 Java 驱动稳定可用的是 3.0.x 系列。不要直接上 3.12 或者 4.x虽然部分 API 兼容但MongoCredential的工厂方法和认证协商细节在跨大版本时有差异。下面这个 pom 片段可以直接复制dependencies dependency groupIdorg.mongodb/groupId artifactIdmongo-java-driver/artifactId version3.0.4/version /dependency /dependencies如果你用的是 Gradle对应写法是compile org.mongodb:mongo-java-driver:3.0.4。这个版本里MongoClientURI、MongoCredential、ServerAddress都在collection.find().into(new ArrayListDocument())这种写法也能正常编译。接下来说 TaoToken 的配置入口。很多同学在排查连接报错时会想找个模型帮忙读日志、解释异常栈。TaoToken 提供统一的 API 接入Base URL 是https://taotoken.net/api你需要在控制台生成 API Key然后在客户端里填三件套Base URL、Key、Model ID。控制台地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsoleAPI Key 管理在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys。如果你只是想让模型帮你解释一段异常用模型对话入口就行https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat。要是你打算长期用编码助手来辅助写这类连接代码可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan。这里要强调一点TaoToken 是模型 API 的接入层不是数据库代理也不替代你的 MongoDB 实例。它解决的是「你写代码时想有个助手帮你查文档、读报错」的问题数据库连接本身还是走你自己的 MongoDB 地址。准备阶段还有两个检查项。第一确认 MongoDB 3.0 实例的启动参数有没有加--auth。这决定了你用哪种连接方式。第二确认网络可达telnet 192.168.100.140 27017能通再往下写代码。这两步不做后面报错会很难定位。3. 可复制的连接配置非认证模式与认证模式这一节给出两套完整可复制的配置分别对应 MongoDB 没开认证和开了--auth的情况。你可以根据自己实例的启动方式选一套。3.1 非认证模式的 MongoClientURI 写法当 MongoDB 启动时没有加--auth连接串里直接带库名即可。下面这段代码可以直接放进测试类import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.ArrayList; import java.util.List; public class MongoNoAuthTest { public static void main(String[] args) { MongoClientURI uri new MongoClientURI( mongodb://192.168.100.140:27017/local, com.mongodb.MongoClientOptions.builder() .cursorFinalizerEnabled(false) .connectTimeout(5000) .serverSelectionTimeout(5000) ); MongoClient client new MongoClient(uri); MongoDatabase db client.getDatabase(local); MongoCollectionDocument collection db.getCollection(system.users); ListDocument foundDocument collection.find().into(new ArrayListDocument()); System.out.println(foundDocument); client.close(); } }这里有两个参数值得单独说。connectTimeout(5000)控制的是 TCP 建连超时单位毫秒serverSelectionTimeout(5000)控制的是驱动在集群里选一个可用节点的时间。MongoDB 3.0 单机部署时后者影响不大但如果你连的是副本集这个值设太小会频繁抛MongoTimeoutException。cursorFinalizerEnabled(false)是关掉游标终结器的后台清理减少 GC 压力老项目里常见。3.2 认证模式的 ServerAddress MongoCredential 写法当 MongoDB 用--auth启动后必须显式传认证信息。注意认证库和业务库的区别createScramSha1Credential的第二个参数是认证数据库通常是admin而getDatabase拿的是你要操作的库。import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class MongoAuthTest { public static void main(String[] args) { ServerAddress serverAddress new ServerAddress(192.168.100.140, 27017); ListServerAddress seeds new ArrayListServerAddress(); seeds.add(serverAddress); MongoCredential credential MongoCredential.createScramSha1Credential( admin, admin, admin.toCharArray() ); ListMongoCredential credentialsList new ArrayListMongoCredential(); credentialsList.add(credential); MongoClient client new MongoClient(seeds, credentialsList); MongoDatabase db client.getDatabase(admin); MongoCollectionDocument collection db.getCollection(system.users); ListDocument foundDocument collection.find().into(new ArrayListDocument()); System.out.println(foundDocument); client.close(); } }把这两套配置整理成对照表方便你按场景选场景构造方式认证对象关键参数未开 authMongoClientURI无connectTimeout、cursorFinalizerEnabled开启 authServerAddress MongoCredentialcreateScramSha1Credential认证库、用户名、密码如果你在项目里用配置文件管理这些参数可以写成 JSON 或 TOML。比如一个mongo-config.json{ host: 192.168.100.140, port: 27017, authEnabled: true, authDatabase: admin, username: admin, password: admin, connectTimeoutMs: 5000, serverSelectionTimeoutMs: 5000 }读取时根据authEnabled分支走上面两套逻辑。这样切换环境时不用改代码。4. 验证请求用一次 insert/find 确认连接真正可用光打印system.users还不够因为那个集合可能为空你看到空列表会误以为连接失败。更可靠的验证是自己建一个集合插一条文档再查出来。下面这段代码在认证模式下完成一次完整写入和读取import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.FindIterable; import org.bson.Document; import java.util.ArrayList; import java.util.List; public class MongoVerifyTest { public static void main(String[] args) { ServerAddress serverAddress new ServerAddress(192.168.100.140, 27017); ListServerAddress seeds new ArrayListServerAddress(); seeds.add(serverAddress); MongoCredential credential MongoCredential.createScramSha1Credential( admin, admin, admin.toCharArray() ); ListMongoCredential credentialsList new ArrayListMongoCredential(); credentialsList.add(credential); MongoClient client new MongoClient(seeds, credentialsList); MongoDatabase db client.getDatabase(testdb); MongoCollectionDocument collection db.getCollection(conn_check); Document doc new Document(name, java-conn-test) .append(ts, System.currentTimeMillis()) .append(ok, true); collection.insertOne(doc); System.out.println(insert done, id doc.getObjectId(_id)); FindIterableDocument iterable collection.find(new Document(name, java-conn-test)); for (Document d : iterable) { System.out.println(found: d.toJson()); } long count collection.count(); System.out.println(collection count count); client.close(); } }运行后你应该看到类似输出insert done, idObjectId(...) found: { _id : { $oid : ... }, name : java-conn-test, ts : 1710000000000, ok : true } collection count1看到found那行有真实文档说明认证、建连、写入、查询四个环节全通了。如果insert成功但find为空检查是不是查了不同的库或集合名。如果count返回 0 但insert没报错可能是写到了另一个库。非认证模式下把构造部分换成MongoClientURI那套即可其余验证逻辑一样。这一步做完你就有底气说「Java 连 MongoDB 3.0 跑通了」。5. 常见报错排查401、超时与认证失败这一节按真实报错来对照方便你快速定位。报错一com.mongodb.MongoSecurityException: Exception authenticating MongoCredential这是认证失败。常见原因有三个用户名密码错、认证库填错、认证机制不匹配。MongoDB 3.0 默认用 SCRAM-SHA-1如果你用createMongoCredential的旧方法可能协商失败。确认你用的是createScramSha1Credential。另外用户是在哪个库创建的认证库就填哪个。很多人在admin库建用户却把认证库填成业务库必然 401。报错二com.mongodb.MongoTimeoutException: Timed out after 5000 ms while waiting for a server这是选不到可用节点。先telnet确认端口通再检查serverSelectionTimeout是不是设太小。如果是副本集驱动需要发现主节点网络策略要放行所有节点。单机部署时这个报错多半是地址写错或防火墙拦截。报错三java.lang.NoSuchMethodError: com.mongodb.MongoCredential.createScramSha1Credential这是依赖版本不对。createScramSha1Credential在 3.0 之前的驱动里没有。检查 pom 里是不是被其他依赖传递引入了低版本驱动用mvn dependency:tree看实际生效的版本。报错四local proxy failed或连接被重置这类报错通常出现在你通过某个中间层访问数据库时。要确认你的连接地址是直连 MongoDB 实例还是经过了额外转发。如果是转发层配置问题检查转发规则和超时设置。注意这里说的是应用层的连接转发不是网络访问工具。报错五reading choices相关异常如果你在用模型助手读日志时看到reading choices之类的解析错误那多半是模型返回格式和客户端预期不一致。这时候检查你的 Base URL、Key、Model ID 三件套是否填对。TaoToken 的接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc里面有各客户端的配置示例。如果你用的是 Claude Code 这类工具参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaudecode的说明。报错六OAuth相关失败有些客户端走 OAuth 流程获取凭证如果回调地址或 token 过期会报 OAuth 错误。重新生成 Key 再试。注意区分数据库认证是 MongoDB 自己的 SCRAM和模型 API 的 OAuth 是两回事别混在一起排查。排查顺序建议先确认网络通再确认认证信息对再看驱动版本最后看超时参数。大部分问题在前两步就能解决。6. 继续深入从连接验证到日常开发连接跑通只是第一步。接下来你可能会遇到批量写入、索引创建、聚合查询这些操作。MongoDB 3.0 的 Java 驱动里MongoCollection提供了insertMany、createIndex、aggregate等方法用法和insertOne/find类似都是链式调用。如果你在写这些代码时想让助手帮你补全或者解释 API可以用模型对话入口快速问https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat。需要长期在 IDE 里辅助编码的走 Coding Plan 更顺手https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan。API Key 记得在控制台生成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys。最后留一个实用技巧把连接测试写成一个 JUnit 测试方法每次改配置后跑一遍比手动 main 方法可靠。测试里用Before建连接、After关连接断言count大于 0。这样你的连接配置就纳入了持续验证后面换环境时不会手忙脚乱。
返回列表