💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
{% raw %} # MongoDB Java 教程 原文:http://zetcode.com/java/mongodb/ 在本教程中,我们将展示如何在 Java 中使用 MongoDB。 在 ZetCode 上有一个简洁的 [Java 教程](/lang/java/)。 MongoDB 是 NoSQL 跨平台的面向文档的数据库。 它是可用的最受欢迎的数据库之一。 MongoDB 由 MongoDB Inc. 开发,并作为免费和开源软件发布。 MongoDB 中的记录是一个文档,它是由字段和值对组成的数据结构。 MongoDB 文档与 JSON 对象相似。 字段的值可以包括其他文档,数组和文档数组。 MongoDB 将文档存储在集合中。 集合类似于关系数据库中的表以及行中的文档。 ## 安装 MongoDB 以下命令可用于在基于 Debian 的 Linux 上安装 MongoDB。 ```java $ sudo apt-get install mongodb ``` 该命令将安装 MongoDB 随附的必要包。 ```java $ sudo service mongodb status mongodb start/running, process 975 ``` 使用`sudo service mongodb status`命令,我们检查`mongodb`服务器的状态。 ```java $ sudo service mongodb start mongodb start/running, process 6448 ``` `mongodb`服务器由`sudo service mongodb start`命令启动。 ## 建立数据库 `mongo`工具是 MongoDB 的交互式 JavaScript Shell 界面,它为系统管理员提供了一个界面,并为开发者提供了一种直接测试数据库查询和操作的方法。 ```java $ mongo testdb MongoDB shell version v4.0.7 connecting to: mongodb://127.0.0.1:27017/testdb?gssapiServiceName=mongodb ... > db testdb > db.cars.insert({name: "Audi", price: 52642}) > db.cars.insert({name: "Mercedes", price: 57127}) > db.cars.insert({name: "Skoda", price: 9000}) > db.cars.insert({name: "Volvo", price: 29000}) > db.cars.insert({name: "Bentley", price: 350000}) > db.cars.insert({name: "Citroen", price: 21000}) > db.cars.insert({name: "Hummer", price: 41400}) > db.cars.insert({name: "Volkswagen", price: 21600}) ``` 我们创建一个`testdb`数据库,并在`cars`集合中插入八个文档。 ## Java MongoDB 驱动程序 我们使用以下 Maven 声明在项目中包括 MongoDB Java 驱动程序。 ```java <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>x.y.z</version> </dependency> ``` 它是一个多功能的 JAR,它嵌入了核心驱动程序和 BSON。 BSON 是 Binaryary JSON 的缩写,是类似于 JSON 的文档的二进制编码的序列化。 ## Java MongoDB 列出数据库集合 第一个示例连接到`testdb`数据库并检索其集合。 `pom.xml` ```java <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>mongocommand</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.10.2</version> </dependency> </dependencies> </project> ``` 这是我们的`pom.xml`文件。 `com/zetcode/MongoListCollections.java` ```java package com.zetcode; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoDatabase; import java.util.logging.Level; import java.util.logging.Logger; public class MongoListCollections { public static void main(String[] args) { Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); mongoLogger.setLevel(Level.SEVERE); try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { MongoDatabase database = mongoClient.getDatabase("testdb"); for (String name : database.listCollectionNames()) { System.out.println(name); } } } } ``` 该示例连接到`testdb`数据库并检索其所有集合。 ```java Logger mongoLogger = Logger.getLogger("org.mongodb.driver"); mongoLogger.setLevel(Level.SEVERE); ``` 我们为 MongoDB 设置日志记录级别。 我们仅显示严重错误消息。 ```java try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { ``` `MongoClient`类用于连接到 MongoDB 服务器。 它是通过`MongoClients.create()`方法调用创建的。 27017 是 MongoDB 服务器监听的默认端口。 ```java MongoDatabase database = mongoClient.getDatabase("testdb"); ``` 使用`getDatabase()`方法,我们检索了`testdb`数据库。 ```java for (String name : database.listCollectionNames()) { System.out.println(name); } ``` `listCollectionNames()`方法在`testdb`数据库中找到所有集合。 ```java cars cities ``` 在我们的数据库中,我们有这两个集合。 ## Java MongoDB 数据库统计 下一个示例连接到`testdb`数据库并获取其统计信息。 `com/zetcode/MongoCommand.java` ```java package com.zetcode; import com.mongodb.client.MongoClients; import org.bson.Document; import java.util.Map; public class MongoCommand { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); var stats = database.runCommand(new Document("dbstats", 1)); for (Map.Entry<String, Object> set : stats.entrySet()) { System.out.format("%s: %s%n", set.getKey(), set.getValue()); } } } } ``` 该示例连接到`testdb`数据库并执行`dbstats`命令。 它显示了一些数据库统计信息。 ```java var stats = database.runCommand(new Document("dbstats", 1)); ``` 使用`runCommand()`方法,执行`dbstats`命令。 该命令返回`Document`,它表示 MongoDB 文档作为映射。 ```java for (Map.Entry<String, Object> set : stats.entrySet()) { System.out.format("%s: %s%n", set.getKey(), set.getValue()); } ``` 我们遍历文档的条目。 ```java db: testdb collections: 2 views: 0 objects: 9 avgObjSize: 48.111111111111114 dataSize: 433.0 storageSize: 57344.0 numExtents: 0 indexes: 2 indexSize: 57344.0 fsUsedSize: 1.4818904064E11 fsTotalSize: 2.547211264E11 ok: 1.0 ``` 这是一个示例输出。 ## Java MongoDB 读取数据 `MongoCollection`用于存储从集合返回的 mongo 文档。 `MongoCursor`是一个游标,用于遍历数据库查询的结果。 确保在发生异常时将其关闭。 `com/zetcode/MongoReadAll.java` ```java package com.zetcode; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import org.bson.Document; import java.util.ArrayList; public class MongoReadAll { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); try (MongoCursor<Document> cur = collection.find().iterator()) { while (cur.hasNext()) { var doc = cur.next(); var cars = new ArrayList<>(doc.values()); System.out.printf("%s: %s%n", cars.get(1), cars.get(2)); } } } } } ``` 在示例中,我们遍历`cars`集合的所有数据。 ```java MongoCollection<Document> collection = database.getCollection("cars"); ``` 我们使用`getCollection()`方法检索`cars`集合。 ```java try (MongoCursor<Document> cur = collection.find().iterator()) { while (cur.hasNext()) { var doc = cur.next(); var cars = new ArrayList<>(doc.values()); System.out.printf("%s: %s%n", cars.get(1), cars.get(2)); } } ``` 我们遍历集合的文档。 `find()`方法查找集合中的所有文档。 ```java Audi: 52642.0 Mercedes: 57127.0 Skoda: 9000.0 Volvo: 29000.0 Bentley: 350000.0 Citroen: 21000.0 Hummer: 41400.0 Volkswagen: 21600.0 ``` 这是示例的输出。 ## Java MongoDB 查询运算符 可以使用 MongoDB 查询运算符(例如`$gt`,`$lt`或`$ne`)过滤数据。 可以在`BasicDBObject`类中指定查询运算符。 `com/zetcode/MongoReadGreaterThan.java` ```java package com.zetcode; import com.mongodb.BasicDBObject; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.function.Consumer; public class MongoReadGreaterThan { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); var query = new BasicDBObject("price", new BasicDBObject("$gt", 30000)); collection.find(query).forEach((Consumer<Document>) doc -> System.out.println(doc.toJson())); } } } ``` 该示例打印汽车价格大于 30,000 的所有文档。 ```java var query = new BasicDBObject("price", new BasicDBObject("$gt", 30000)); ``` 我们使用`$gt`查询运算符。 ```java collection.find(query).forEach((Consumer<Document>) doc -> System.out.println(doc.toJson())); ``` `forEach()`方法是一种语法糖,可以避免应用代码担心不必手动关闭游标。 使用`toJson()`方法以 JSON 格式打印数据。 ```java {"_id": {"$oid": "5d4d13d6463315268eb7376b"}, "name": "Audi", "price": 52642.0} {"_id": {"$oid": "5d4d13f5463315268eb7376c"}, "name": "Mercedes", "price": 57127.0} {"_id": {"$oid": "5d4d140d463315268eb7376f"}, "name": "Bentley", "price": 350000.0} {"_id": {"$oid": "5d4d1415463315268eb73771"}, "name": "Hummer", "price": 41400.0} ``` 这是 JSON 格式的示例输出。 仅包括价格超过 30,000 的汽车。 ## Java MongoDB 工厂过滤器查询方法 Java MongoDB 驱动包含查询过滤器的工厂方法。 `com/zetcode/MongoFilter.java` ```java package com.zetcode; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import org.bson.Document; import java.util.ArrayList; import static com.mongodb.client.model.Filters.and; import static com.mongodb.client.model.Filters.gt; import static com.mongodb.client.model.Filters.lt; public class MongoFilter { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); FindIterable fit = collection.find(and(lt("price", 50000), gt("price", 20000))).sort(new Document("price", -1)); var docs = new ArrayList<Document>(); fit.into(docs); for (Document doc : docs) { System.out.println(doc); } } } } ``` 在示例中,我们检索价格在 20,000 到 50,000 之间的汽车。 ```java FindIterable fit = collection.find(and(lt("price", 50000), gt("price", 20000))).sort(new Document("price", -1)); ``` `and()`,`gt()`和`lt()`是工厂过滤方法。 此外,数据使用`sort()`方法排序。 ```java Document{{_id=5d4d1415463315268eb73771, name=Hummer, price=41400.0}} Document{{_id=5d4d1408463315268eb7376e, name=Volvo, price=29000.0}} Document{{_id=5d4d1419463315268eb73772, name=Volkswagen, price=21600.0}} Document{{_id=5d4d1411463315268eb73770, name=Citroen, price=21000.0}} ``` This is the output of the example. ## Java MongoDB 投影 `Projections`类为所有 MongoDB 投影运算符提供了静态工厂方法。 默认情况下,将投影每个文档的所有字段。 我们可以使用`include`和`exclude()`方法来确定应将哪些字段投影到我们的输出中。 `com/zetcode/MongoProjection.java` ```java package com.zetcode; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.ArrayList; import static com.mongodb.client.model.Projections.excludeId; public class MongoProjection { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); FindIterable it = collection.find().projection(excludeId()); var docs = new ArrayList<Document>(); it.into(docs); for (Document doc : docs) { System.out.println(doc); } } } } ``` 该示例从输出中排除`_id`字段。 ```java FindIterable it = collection.find().projection(excludeId()); ``` `projection()`方法设置一个文档,该文档描述要为所有匹配的文档返回的字段。 `excludeId()`是`exclude("_id")`的同义词。 ```java Document{{name=Audi, price=52642.0}} Document{{name=Mercedes, price=57127.0}} Document{{name=Skoda, price=9000.0}} Document{{name=Volvo, price=29000.0}} Document{{name=Bentley, price=350000.0}} Document{{name=Citroen, price=21000.0}} Document{{name=Hummer, price=41400.0}} Document{{name=Volkswagen, price=21600.0}} ``` 这是示例的输出。 ## Java MongoDB 限制数据输出 `limit`查询选项指定要返回的文档数量,`skip()`选项指定某些文档。 `com/zetcode/MongoSkipLimit.java` ```java package com.zetcode; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.function.Consumer; public class MongoSkipLimit { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); FindIterable<Document> fit = collection.find().skip(2).limit(5); fit.forEach((Consumer<Document>) System.out::println); } } } ``` 该示例从`testdb.cars`集合中读取,跳过前两个文档,并将输出限制为五个文档。 ```java FindIterable<Document> fit = collection.find().skip(2).limit(5); ``` `FindIterable`的`skip()`方法跳过前两个文档,`limit()`方法将输出限制为五个文档。 ```java fit.forEach((Consumer<Document>) System.out::println); ``` 在这里,我们使用 Java8 构造来打印文档。 ```java Document{{_id=5d4d13fb463315268eb7376d, name=Skoda, price=9000.0}} Document{{_id=5d4d1408463315268eb7376e, name=Volvo, price=29000.0}} Document{{_id=5d4d140d463315268eb7376f, name=Bentley, price=350000.0}} Document{{_id=5d4d1411463315268eb73770, name=Citroen, price=21000.0}} Document{{_id=5d4d1415463315268eb73771, name=Hummer, price=41400.0}} ``` This is the output of the example. ## Java MongoDB 创建集合 `MongoDatabase`的`createCollection()`方法在数据库中创建一个新集合。 `MongoCollection`的`insertMany()`方法将一个或多个文档插入到集合中。 `com/zetcode/MongoCreateCollection.java` ```java package com.zetcode; import com.mongodb.MongoCommandException; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import org.bson.Document; import java.util.ArrayList; public class MongoCreateCollection { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); try { database.createCollection("cars"); } catch (MongoCommandException e) { database.getCollection("cars").drop(); } var docs = new ArrayList<Document>(); MongoCollection<Document> collection = database.getCollection("cars"); var d1 = new Document("_id", 1); d1.append("name", "Audi"); d1.append("price", 52642); docs.add(d1); var d2 = new Document("_id", 2); d2.append("name", "Mercedes"); d2.append("price", 57127); docs.add(d2); var d3 = new Document("_id", 3); d3.append("name", "Skoda"); d3.append("price", 9000); docs.add(d3); var d4 = new Document("_id", 4); d4.append("name", "Volvo"); d4.append("price", 29000); docs.add(d4); var d5 = new Document("_id", 5); d5.append("name", "Bentley"); d5.append("price", 350000); docs.add(d5); var d6 = new Document("_id", 6); d6.append("name", "Citroen"); d6.append("price", 21000); docs.add(d6); var d7 = new Document("_id", 7); d7.append("name", "Hummer"); d7.append("price", 41400); docs.add(d7); var d8 = new Document("_id", 8); d8.append("name", "Volkswagen"); d8.append("price", 21600); docs.add(d8); collection.insertMany(docs); } } } ``` 该示例创建一个`cars`集合并将 9 个文档插入其中。 ```java try { database.createCollection("cars"); } catch (MongoCommandException e) { database.getCollection("cars").drop(); } ``` 使用`createCollection()`方法创建一个新集合。 如果该集合已经存在,则将其删除。 ```java MongoCollection<Document> collection = database.getCollection("cars"); ``` 使用`getCollection()`方法创建文档的`MongoCollection`。 ```java var d1 = new Document("_id", 1); d1.append("name", "Audi"); d1.append("price", 52642); docs.add(d1); ``` 创建一个新的`Document`。 它包含有关汽车的信息,包括其 ID,名称和价格。 ```java collection.insertMany(docs); ``` 使用`insertMany()`方法将文档写入集合。 ## Java MongoDB 从 JSON 创建集合 `JSON`类具有用于解析 JSON 文档的方法。 JSON (JavaScript 对象表示法)是一种轻量级的数据交换格式。 人类易于阅读和书写。 `com/zetcode/MongoCollectionFromJSON.java` ```java package com.zetcode; import com.mongodb.BasicDBObject; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import org.bson.Document; import org.bson.types.ObjectId; public class MongoCollectionFromJSON { public static void main(String[] args) { try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("continents"); var africa = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Africa'}"); var asia = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Asia'}"); var europe = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Europe'}"); var america = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'America'}"); var australia = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Australia'}"); var antarctica = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Antarctica'}"); collection.insertOne(new Document(africa)); collection.insertOne(new Document(asia)); collection.insertOne(new Document(europe)); collection.insertOne(new Document(america)); collection.insertOne(new Document(australia)); collection.insertOne(new Document(antarctica)); } } } ``` 该示例从 JSON 数据创建`continents`集合。 ```java var africa = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Africa'}"); ``` JSON 数据使用`BasicDBObject.parse`方法进行解析。 ```java collection.insertOne(new Document(africa)); ``` `BasicDBObject`传递到`Document`,并通过`insertOne()`方法插入到集合中。 ```java > db.continents.find() { "_id" : "5d4af89645ffb636567b6448", "name" : "Africa" } { "_id" : "5d4af89645ffb636567b6449", "name" : "Asia" } { "_id" : "5d4af89645ffb636567b644a", "name" : "Europe" } { "_id" : "5d4af89645ffb636567b644b", "name" : "America" } { "_id" : "5d4af89645ffb636567b644c", "name" : "Australia" } { "_id" : "5d4af89645ffb636567b644d", "name" : "Antarctica" } ``` 我们用`mongo`显示创建的集合。 ## Java MongoDB 修改文件 `MongoCollection`的`deleteOne()`方法用于删除文档,`updateOne()`用于更新文档。 `com/zetcode/MongoModify.java` ```java package com.zetcode; import com.mongodb.MongoClient; import com.mongodb.client.MongoCollection; import org.bson.Document; import static com.mongodb.client.model.Filters.eq; public class MongoModify { public static void main(String[] args) { try (var mongoClient = new MongoClient("localhost", 27017)) { var database = mongoClient.getDatabase("testdb"); MongoCollection<Document> collection = database.getCollection("cars"); collection.deleteOne(eq("name", "Skoda")); collection.updateOne(new Document("name", "Audi"), new Document("$set", new Document("price", 52000))); } } } ``` 该示例删除包含 Skoda 的文档并更新 Audi 的价格。 ```java collection.deleteOne(eq("name", "Skoda")); ``` `deleteOne()`删除`Skoda`的文档。 `eq()`创建一个与所有文档匹配的过滤器,其中字段名称的值等于指定的值。 ```java collection.updateOne(new Document("name", "Audi"), new Document("$set", new Document("price", 52000))); ``` 通过`updateOne()`方法将 Audi 的价格更改为 52,000。 ```java > db.cars.find() { "_id" : ObjectId("5d4d13d6463315268eb7376b"), "name" : "Audi", "price" : 52000 } { "_id" : ObjectId("5d4d13f5463315268eb7376c"), "name" : "Mercedes", "price" : 57127 } { "_id" : ObjectId("5d4d1408463315268eb7376e"), "name" : "Volvo", "price" : 29000 } { "_id" : ObjectId("5d4d140d463315268eb7376f"), "name" : "Bentley", "price" : 350000 } { "_id" : ObjectId("5d4d1411463315268eb73770"), "name" : "Citroen", "price" : 21000 } { "_id" : ObjectId("5d4d1415463315268eb73771"), "name" : "Hummer", "price" : 41400 } { "_id" : ObjectId("5d4d1419463315268eb73772"), "name" : "Volkswagen", "price" : 21600 } ``` 我们使用`mongo`工具确认更改。 在本教程中,我们使用了 MongoDB 和 Java。 您可能也对 [Spring Boot MongoDB 教程](/springboot/mongodb/), [MySQL Java 教程](/db/mysqljava/)或 [PostgreSQL Java 教程](/java/postgresql/)感兴趣。 列出[所有 Java 教程](/all/#java)。 {% endraw %}