{% raw %}

MongoDB Java 教程

原文:http://zetcode.com/java/mongodb/

在本教程中,我们将展示如何在 Java 中使用 MongoDB。 在 ZetCode 上有一个简洁的 Java 教程

MongoDB 是 NoSQL 跨平台的面向文档的数据库。 它是可用的最受欢迎的数据库之一。 MongoDB 由 MongoDB Inc. 开发,并作为免费和开源软件发布。

MongoDB 中的记录是一个文档,它是由字段和值对组成的数据结构。 MongoDB 文档与 JSON 对象相似。 字段的值可以包括其他文档,数组和文档数组。 MongoDB 将文档存储在集合中。 集合类似于关系数据库中的表以及行中的文档。

安装 MongoDB

以下命令可用于在基于 Debian 的 Linux 上安装 MongoDB。

  1. $ sudo apt-get install mongodb

该命令将安装 MongoDB 随附的必要包。

  1. $ sudo service mongodb status
  2. mongodb start/running, process 975

使用sudo service mongodb status命令,我们检查mongodb服务器的状态。

  1. $ sudo service mongodb start
  2. mongodb start/running, process 6448

mongodb服务器由sudo service mongodb start命令启动。

建立数据库

mongo工具是 MongoDB 的交互式 JavaScript Shell 界面,它为系统管理员提供了一个界面,并为开发者提供了一种直接测试数据库查询和操作的方法。

  1. $ mongo testdb
  2. MongoDB shell version v4.0.7
  3. connecting to: mongodb://127.0.0.1:27017/testdb?gssapiServiceName=mongodb
  4. ...
  5. > db
  6. testdb
  7. > db.cars.insert({name: "Audi", price: 52642})
  8. > db.cars.insert({name: "Mercedes", price: 57127})
  9. > db.cars.insert({name: "Skoda", price: 9000})
  10. > db.cars.insert({name: "Volvo", price: 29000})
  11. > db.cars.insert({name: "Bentley", price: 350000})
  12. > db.cars.insert({name: "Citroen", price: 21000})
  13. > db.cars.insert({name: "Hummer", price: 41400})
  14. > db.cars.insert({name: "Volkswagen", price: 21600})

我们创建一个testdb数据库,并在cars集合中插入八个文档。

Java MongoDB 驱动程序

我们使用以下 Maven 声明在项目中包括 MongoDB Java 驱动程序。

  1. <dependency>
  2. <groupId>org.mongodb</groupId>
  3. <artifactId>mongo-java-driver</artifactId>
  4. <version>x.y.z</version>
  5. </dependency>

它是一个多功能的 JAR,它嵌入了核心驱动程序和 BSON。 BSON 是 Binaryary JSON 的缩写,是类似于 JSON 的文档的二进制编码的序列化。

Java MongoDB 列出数据库集合

第一个示例连接到testdb数据库并检索其集合。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>mongocommand</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.mongodb</groupId>
  19. <artifactId>mongo-java-driver</artifactId>
  20. <version>3.10.2</version>
  21. </dependency>
  22. </dependencies>
  23. </project>

这是我们的pom.xml文件。

com/zetcode/MongoListCollections.java

  1. package com.zetcode;
  2. import com.mongodb.client.MongoClients;
  3. import com.mongodb.client.MongoDatabase;
  4. import java.util.logging.Level;
  5. import java.util.logging.Logger;
  6. public class MongoListCollections {
  7. public static void main(String[] args) {
  8. Logger mongoLogger = Logger.getLogger("org.mongodb.driver");
  9. mongoLogger.setLevel(Level.SEVERE);
  10. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  11. MongoDatabase database = mongoClient.getDatabase("testdb");
  12. for (String name : database.listCollectionNames()) {
  13. System.out.println(name);
  14. }
  15. }
  16. }
  17. }

该示例连接到testdb数据库并检索其所有集合。

  1. Logger mongoLogger = Logger.getLogger("org.mongodb.driver");
  2. mongoLogger.setLevel(Level.SEVERE);

我们为 MongoDB 设置日志记录级别。 我们仅显示严重错误消息。

  1. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {

MongoClient类用于连接到 MongoDB 服务器。 它是通过MongoClients.create()方法调用创建的。 27017 是 MongoDB 服务器监听的默认端口。

  1. MongoDatabase database = mongoClient.getDatabase("testdb");

使用getDatabase()方法,我们检索了testdb数据库。

  1. for (String name : database.listCollectionNames()) {
  2. System.out.println(name);
  3. }

listCollectionNames()方法在testdb数据库中找到所有集合。

  1. cars
  2. cities

在我们的数据库中,我们有这两个集合。

Java MongoDB 数据库统计

下一个示例连接到testdb数据库并获取其统计信息。

com/zetcode/MongoCommand.java

  1. package com.zetcode;
  2. import com.mongodb.client.MongoClients;
  3. import org.bson.Document;
  4. import java.util.Map;
  5. public class MongoCommand {
  6. public static void main(String[] args) {
  7. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  8. var database = mongoClient.getDatabase("testdb");
  9. var stats = database.runCommand(new Document("dbstats", 1));
  10. for (Map.Entry<String, Object> set : stats.entrySet()) {
  11. System.out.format("%s: %s%n", set.getKey(), set.getValue());
  12. }
  13. }
  14. }
  15. }

该示例连接到testdb数据库并执行dbstats命令。 它显示了一些数据库统计信息。

  1. var stats = database.runCommand(new Document("dbstats", 1));

使用runCommand()方法,执行dbstats命令。 该命令返回Document,它表示 MongoDB 文档作为映射。

  1. for (Map.Entry<String, Object> set : stats.entrySet()) {
  2. System.out.format("%s: %s%n", set.getKey(), set.getValue());
  3. }

我们遍历文档的条目。

  1. db: testdb
  2. collections: 2
  3. views: 0
  4. objects: 9
  5. avgObjSize: 48.111111111111114
  6. dataSize: 433.0
  7. storageSize: 57344.0
  8. numExtents: 0
  9. indexes: 2
  10. indexSize: 57344.0
  11. fsUsedSize: 1.4818904064E11
  12. fsTotalSize: 2.547211264E11
  13. ok: 1.0

这是一个示例输出。

Java MongoDB 读取数据

MongoCollection用于存储从集合返回的 mongo 文档。 MongoCursor是一个游标,用于遍历数据库查询的结果。 确保在发生异常时将其关闭。

com/zetcode/MongoReadAll.java

  1. package com.zetcode;
  2. import com.mongodb.client.MongoClients;
  3. import com.mongodb.client.MongoCollection;
  4. import com.mongodb.client.MongoCursor;
  5. import org.bson.Document;
  6. import java.util.ArrayList;
  7. public class MongoReadAll {
  8. public static void main(String[] args) {
  9. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  10. var database = mongoClient.getDatabase("testdb");
  11. MongoCollection<Document> collection = database.getCollection("cars");
  12. try (MongoCursor<Document> cur = collection.find().iterator()) {
  13. while (cur.hasNext()) {
  14. var doc = cur.next();
  15. var cars = new ArrayList<>(doc.values());
  16. System.out.printf("%s: %s%n", cars.get(1), cars.get(2));
  17. }
  18. }
  19. }
  20. }
  21. }

在示例中,我们遍历cars集合的所有数据。

  1. MongoCollection<Document> collection = database.getCollection("cars");

我们使用getCollection()方法检索cars集合。

  1. try (MongoCursor<Document> cur = collection.find().iterator()) {
  2. while (cur.hasNext()) {
  3. var doc = cur.next();
  4. var cars = new ArrayList<>(doc.values());
  5. System.out.printf("%s: %s%n", cars.get(1), cars.get(2));
  6. }
  7. }

我们遍历集合的文档。 find()方法查找集合中的所有文档。

  1. Audi: 52642.0
  2. Mercedes: 57127.0
  3. Skoda: 9000.0
  4. Volvo: 29000.0
  5. Bentley: 350000.0
  6. Citroen: 21000.0
  7. Hummer: 41400.0
  8. Volkswagen: 21600.0

这是示例的输出。

Java MongoDB 查询运算符

可以使用 MongoDB 查询运算符(例如$gt$lt$ne)过滤数据。 可以在BasicDBObject类中指定查询运算符。

com/zetcode/MongoReadGreaterThan.java

  1. package com.zetcode;
  2. import com.mongodb.BasicDBObject;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import org.bson.Document;
  6. import java.util.function.Consumer;
  7. public class MongoReadGreaterThan {
  8. public static void main(String[] args) {
  9. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  10. var database = mongoClient.getDatabase("testdb");
  11. MongoCollection<Document> collection = database.getCollection("cars");
  12. var query = new BasicDBObject("price",
  13. new BasicDBObject("$gt", 30000));
  14. collection.find(query).forEach((Consumer<Document>) doc ->
  15. System.out.println(doc.toJson()));
  16. }
  17. }
  18. }

该示例打印汽车价格大于 30,000 的所有文档。

  1. var query = new BasicDBObject("price",
  2. new BasicDBObject("$gt", 30000));

我们使用$gt查询运算符。

  1. collection.find(query).forEach((Consumer<Document>) doc ->
  2. System.out.println(doc.toJson()));

forEach()方法是一种语法糖,可以避免应用代码担心不必手动关闭游标。 使用toJson()方法以 JSON 格式打印数据。

  1. {"_id": {"$oid": "5d4d13d6463315268eb7376b"}, "name": "Audi", "price": 52642.0}
  2. {"_id": {"$oid": "5d4d13f5463315268eb7376c"}, "name": "Mercedes", "price": 57127.0}
  3. {"_id": {"$oid": "5d4d140d463315268eb7376f"}, "name": "Bentley", "price": 350000.0}
  4. {"_id": {"$oid": "5d4d1415463315268eb73771"}, "name": "Hummer", "price": 41400.0}

这是 JSON 格式的示例输出。 仅包括价格超过 30,000 的汽车。

Java MongoDB 工厂过滤器查询方法

Java MongoDB 驱动包含查询过滤器的工厂方法。

com/zetcode/MongoFilter.java

  1. package com.zetcode;
  2. import com.mongodb.client.FindIterable;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import com.mongodb.client.MongoDatabase;
  6. import org.bson.Document;
  7. import java.util.ArrayList;
  8. import static com.mongodb.client.model.Filters.and;
  9. import static com.mongodb.client.model.Filters.gt;
  10. import static com.mongodb.client.model.Filters.lt;
  11. public class MongoFilter {
  12. public static void main(String[] args) {
  13. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  14. var database = mongoClient.getDatabase("testdb");
  15. MongoCollection<Document> collection = database.getCollection("cars");
  16. FindIterable fit = collection.find(and(lt("price", 50000),
  17. gt("price", 20000))).sort(new Document("price", -1));
  18. var docs = new ArrayList<Document>();
  19. fit.into(docs);
  20. for (Document doc : docs) {
  21. System.out.println(doc);
  22. }
  23. }
  24. }
  25. }

在示例中,我们检索价格在 20,000 到 50,000 之间的汽车。

  1. FindIterable fit = collection.find(and(lt("price", 50000),
  2. gt("price", 20000))).sort(new Document("price", -1));

and()gt()lt()是工厂过滤方法。 此外,数据使用sort()方法排序。

  1. Document{{_id=5d4d1415463315268eb73771, name=Hummer, price=41400.0}}
  2. Document{{_id=5d4d1408463315268eb7376e, name=Volvo, price=29000.0}}
  3. Document{{_id=5d4d1419463315268eb73772, name=Volkswagen, price=21600.0}}
  4. Document{{_id=5d4d1411463315268eb73770, name=Citroen, price=21000.0}}

This is the output of the example.

Java MongoDB 投影

Projections类为所有 MongoDB 投影运算符提供了静态工厂方法。 默认情况下,将投影每个文档的所有字段。 我们可以使用includeexclude()方法来确定应将哪些字段投影到我们的输出中。

com/zetcode/MongoProjection.java

  1. package com.zetcode;
  2. import com.mongodb.client.FindIterable;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import org.bson.Document;
  6. import java.util.ArrayList;
  7. import static com.mongodb.client.model.Projections.excludeId;
  8. public class MongoProjection {
  9. public static void main(String[] args) {
  10. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  11. var database = mongoClient.getDatabase("testdb");
  12. MongoCollection<Document> collection = database.getCollection("cars");
  13. FindIterable it = collection.find().projection(excludeId());
  14. var docs = new ArrayList<Document>();
  15. it.into(docs);
  16. for (Document doc : docs) {
  17. System.out.println(doc);
  18. }
  19. }
  20. }
  21. }

该示例从输出中排除_id字段。

  1. FindIterable it = collection.find().projection(excludeId());

projection()方法设置一个文档,该文档描述要为所有匹配的文档返回的字段。 excludeId()exclude("_id")的同义词。

  1. Document{{name=Audi, price=52642.0}}
  2. Document{{name=Mercedes, price=57127.0}}
  3. Document{{name=Skoda, price=9000.0}}
  4. Document{{name=Volvo, price=29000.0}}
  5. Document{{name=Bentley, price=350000.0}}
  6. Document{{name=Citroen, price=21000.0}}
  7. Document{{name=Hummer, price=41400.0}}
  8. Document{{name=Volkswagen, price=21600.0}}

这是示例的输出。

Java MongoDB 限制数据输出

limit查询选项指定要返回的文档数量,skip()选项指定某些文档。

com/zetcode/MongoSkipLimit.java

  1. package com.zetcode;
  2. import com.mongodb.client.FindIterable;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import org.bson.Document;
  6. import java.util.function.Consumer;
  7. public class MongoSkipLimit {
  8. public static void main(String[] args) {
  9. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  10. var database = mongoClient.getDatabase("testdb");
  11. MongoCollection<Document> collection = database.getCollection("cars");
  12. FindIterable<Document> fit = collection.find().skip(2).limit(5);
  13. fit.forEach((Consumer<Document>) System.out::println);
  14. }
  15. }
  16. }

该示例从testdb.cars集合中读取,跳过前两个文档,并将输出限制为五个文档。

  1. FindIterable<Document> fit = collection.find().skip(2).limit(5);

FindIterableskip()方法跳过前两个文档,limit()方法将输出限制为五个文档。

  1. fit.forEach((Consumer<Document>) System.out::println);

在这里,我们使用 Java8 构造来打印文档。

  1. Document{{_id=5d4d13fb463315268eb7376d, name=Skoda, price=9000.0}}
  2. Document{{_id=5d4d1408463315268eb7376e, name=Volvo, price=29000.0}}
  3. Document{{_id=5d4d140d463315268eb7376f, name=Bentley, price=350000.0}}
  4. Document{{_id=5d4d1411463315268eb73770, name=Citroen, price=21000.0}}
  5. Document{{_id=5d4d1415463315268eb73771, name=Hummer, price=41400.0}}

This is the output of the example.

Java MongoDB 创建集合

MongoDatabasecreateCollection()方法在数据库中创建一个新集合。 MongoCollectioninsertMany()方法将一个或多个文档插入到集合中。

com/zetcode/MongoCreateCollection.java

  1. package com.zetcode;
  2. import com.mongodb.MongoCommandException;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import org.bson.Document;
  6. import java.util.ArrayList;
  7. public class MongoCreateCollection {
  8. public static void main(String[] args) {
  9. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  10. var database = mongoClient.getDatabase("testdb");
  11. try {
  12. database.createCollection("cars");
  13. } catch (MongoCommandException e) {
  14. database.getCollection("cars").drop();
  15. }
  16. var docs = new ArrayList<Document>();
  17. MongoCollection<Document> collection = database.getCollection("cars");
  18. var d1 = new Document("_id", 1);
  19. d1.append("name", "Audi");
  20. d1.append("price", 52642);
  21. docs.add(d1);
  22. var d2 = new Document("_id", 2);
  23. d2.append("name", "Mercedes");
  24. d2.append("price", 57127);
  25. docs.add(d2);
  26. var d3 = new Document("_id", 3);
  27. d3.append("name", "Skoda");
  28. d3.append("price", 9000);
  29. docs.add(d3);
  30. var d4 = new Document("_id", 4);
  31. d4.append("name", "Volvo");
  32. d4.append("price", 29000);
  33. docs.add(d4);
  34. var d5 = new Document("_id", 5);
  35. d5.append("name", "Bentley");
  36. d5.append("price", 350000);
  37. docs.add(d5);
  38. var d6 = new Document("_id", 6);
  39. d6.append("name", "Citroen");
  40. d6.append("price", 21000);
  41. docs.add(d6);
  42. var d7 = new Document("_id", 7);
  43. d7.append("name", "Hummer");
  44. d7.append("price", 41400);
  45. docs.add(d7);
  46. var d8 = new Document("_id", 8);
  47. d8.append("name", "Volkswagen");
  48. d8.append("price", 21600);
  49. docs.add(d8);
  50. collection.insertMany(docs);
  51. }
  52. }
  53. }

该示例创建一个cars集合并将 9 个文档插入其中。

  1. try {
  2. database.createCollection("cars");
  3. } catch (MongoCommandException e) {
  4. database.getCollection("cars").drop();
  5. }

使用createCollection()方法创建一个新集合。 如果该集合已经存在,则将其删除。

  1. MongoCollection<Document> collection = database.getCollection("cars");

使用getCollection()方法创建文档的MongoCollection

  1. var d1 = new Document("_id", 1);
  2. d1.append("name", "Audi");
  3. d1.append("price", 52642);
  4. docs.add(d1);

创建一个新的Document。 它包含有关汽车的信息,包括其 ID,名称和价格。

  1. collection.insertMany(docs);

使用insertMany()方法将文档写入集合。

Java MongoDB 从 JSON 创建集合

JSON类具有用于解析 JSON 文档的方法。 JSON (JavaScript 对象表示法)是一种轻量级的数据交换格式。 人类易于阅读和书写。

com/zetcode/MongoCollectionFromJSON.java

  1. package com.zetcode;
  2. import com.mongodb.BasicDBObject;
  3. import com.mongodb.client.MongoClients;
  4. import com.mongodb.client.MongoCollection;
  5. import org.bson.Document;
  6. import org.bson.types.ObjectId;
  7. public class MongoCollectionFromJSON {
  8. public static void main(String[] args) {
  9. try (var mongoClient = MongoClients.create("mongodb://localhost:27017")) {
  10. var database = mongoClient.getDatabase("testdb");
  11. MongoCollection<Document> collection = database.getCollection("continents");
  12. var africa = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Africa'}");
  13. var asia = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Asia'}");
  14. var europe = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Europe'}");
  15. var america = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'America'}");
  16. var australia = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Australia'}");
  17. var antarctica = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Antarctica'}");
  18. collection.insertOne(new Document(africa));
  19. collection.insertOne(new Document(asia));
  20. collection.insertOne(new Document(europe));
  21. collection.insertOne(new Document(america));
  22. collection.insertOne(new Document(australia));
  23. collection.insertOne(new Document(antarctica));
  24. }
  25. }
  26. }

该示例从 JSON 数据创建continents集合。

  1. var africa = BasicDBObject.parse("{_id : '" + ObjectId.get() + "', name : 'Africa'}");

JSON 数据使用BasicDBObject.parse方法进行解析。

  1. collection.insertOne(new Document(africa));

BasicDBObject传递到Document,并通过insertOne()方法插入到集合中。

  1. > db.continents.find()
  2. { "_id" : "5d4af89645ffb636567b6448", "name" : "Africa" }
  3. { "_id" : "5d4af89645ffb636567b6449", "name" : "Asia" }
  4. { "_id" : "5d4af89645ffb636567b644a", "name" : "Europe" }
  5. { "_id" : "5d4af89645ffb636567b644b", "name" : "America" }
  6. { "_id" : "5d4af89645ffb636567b644c", "name" : "Australia" }
  7. { "_id" : "5d4af89645ffb636567b644d", "name" : "Antarctica" }

我们用mongo显示创建的集合。

Java MongoDB 修改文件

MongoCollectiondeleteOne()方法用于删除文档,updateOne()用于更新文档。

com/zetcode/MongoModify.java

  1. package com.zetcode;
  2. import com.mongodb.MongoClient;
  3. import com.mongodb.client.MongoCollection;
  4. import org.bson.Document;
  5. import static com.mongodb.client.model.Filters.eq;
  6. public class MongoModify {
  7. public static void main(String[] args) {
  8. try (var mongoClient = new MongoClient("localhost", 27017)) {
  9. var database = mongoClient.getDatabase("testdb");
  10. MongoCollection<Document> collection = database.getCollection("cars");
  11. collection.deleteOne(eq("name", "Skoda"));
  12. collection.updateOne(new Document("name", "Audi"),
  13. new Document("$set", new Document("price", 52000)));
  14. }
  15. }
  16. }

该示例删除包含 Skoda 的文档并更新 Audi 的价格。

  1. collection.deleteOne(eq("name", "Skoda"));

deleteOne()删除Skoda的文档。 eq()创建一个与所有文档匹配的过滤器,其中字段名称的值等于指定的值。

  1. collection.updateOne(new Document("name", "Audi"),
  2. new Document("$set", new Document("price", 52000)));

通过updateOne()方法将 Audi 的价格更改为 52,000。

  1. > db.cars.find()
  2. { "_id" : ObjectId("5d4d13d6463315268eb7376b"), "name" : "Audi", "price" : 52000 }
  3. { "_id" : ObjectId("5d4d13f5463315268eb7376c"), "name" : "Mercedes", "price" : 57127 }
  4. { "_id" : ObjectId("5d4d1408463315268eb7376e"), "name" : "Volvo", "price" : 29000 }
  5. { "_id" : ObjectId("5d4d140d463315268eb7376f"), "name" : "Bentley", "price" : 350000 }
  6. { "_id" : ObjectId("5d4d1411463315268eb73770"), "name" : "Citroen", "price" : 21000 }
  7. { "_id" : ObjectId("5d4d1415463315268eb73771"), "name" : "Hummer", "price" : 41400 }
  8. { "_id" : ObjectId("5d4d1419463315268eb73772"), "name" : "Volkswagen", "price" : 21600 }

我们使用mongo工具确认更改。

在本教程中,我们使用了 MongoDB 和 Java。 您可能也对 Spring Boot MongoDB 教程MySQL Java 教程PostgreSQL Java 教程感兴趣。

列出所有 Java 教程

{% endraw %}