MongoDB Java Driver操作指南

MongoDB爲Java提供了非常豐富的API操作,相比關係型數據庫,這種NoSQL本身的數據也有點面向對象的意思,所以對於Java來說,Mongo的數據結構更加友好。

MongoDB在今年做了一次重大升級,版本來到了3.0。
相比之前的版本,這個版本中又很大的變化,相應地,本文中的方法可能在舊的版本中無法使用。

安裝MongoDB Java Driver

使用maven的用戶在pom.xml中使用以下的dependency。

<dependency>
   <groupId>org.mongodb</groupId>
   <artifactId>mongodb-driver</artifactId>
   <version>3.1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.1.0-SNAPSHOT</version>
</dependency>

建立連接

程序可以通過MongoClient這個類和MongoDB數據庫建立連接。


MongoClient mongoClient = new MongoClient();

// or
MongoClient mongoClient = new MongoClient( "localhost" );

// or
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

// or, 連接副本集,MongoClient會自動識別出
MongoClient mongoClient = new MongoClient(
  Arrays.asList(new ServerAddress("localhost", 27017),
                new ServerAddress("localhost", 27018),
                new ServerAddress("localhost", 27019)));

MongoDatabase database = mongoClient.getDatabase("mydb");

如果mydb不存在的話,那麼Mongo也會給我們新創建一個數據庫。

MongoDatabase的本質就是一個數據庫的連接,而MongoClient是一個Client,所以我們在應用中可能需要多個連接,卻只需要創建一個MongoClient就可以了,MongoClient本身封裝了一個連接池。關於MongoClient,後面再補一篇文章。

獲得集合

在得到連接之後,通過getCollection()方法來獲取,相同地,如果獲取的集合不存在,那麼Mongo會爲我們創建這個集合。

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

插入一個文檔

在MongoDB中,數據都是以文檔的形式存在的,一個集合可以理解成一個“文檔鏈”。

在獲得集合之後,程序就可以通過集合來插入一個新的數據了。

在Mongo Java API中,文檔對應的類是Document , 文檔中間還可以內嵌文檔。

比如插入這樣的數據

{
	"username" : "whthomas",
	"age" : "22",
	"location":{
		"city" : "hangzhou",
		"x" : 100,
		"y" : 200
	}
}
Document doc = new Document("username","whthomas").append("age", "22").append("location", new Document("city", "hangzhou").append("x", 100).append("y","200"));

collection.insertOne(doc);

如果要插入多個文檔。使用insertMany()函數效率會更高一些,這個函數接受一個List< Document >類型。

List<Document> documents = new ArrayList<Document>();
for (int i = 0; i < 100; i++) {
    documents.add(new Document("i", i));
}

collection.insertMany(documents);

查詢操作

查詢操作數據庫操作中相對比較複雜的操作,在MongoDB中通過集合的find()方法來查詢數據。

find()函數會返回FindIterable,它提供了一個接口給程序操作和控制這個集合。

得到第一條數據

使用first()函數可以得到結果集中的第一條數據,如果沒有找到數據,則返回一個null值。

Document myDoc = collection.find().first();

得到所有數據

通過iterator方法將FindIterable對象轉換成一個MongoCursor對象。

MongoCursor<Document> cursor = collection.find().iterator();
try {
    while (cursor.hasNext()) {
	System.out.println(cursor.next().toJson());
    }
} finally {
    cursor.close();
}

條件查詢

MongoDB的Java條件查詢操作,在我看來有些不那麼面向對象,寫起來有點函數式編程的味道。

通過Filters、Sorts和Projections三個類,我們可以完成複雜的查詢操作。

比如程序需要得到一個指定條件的數據

import static com.mongodb.client.model.Filters.*;

Document myDoc = collection.find(eq("i", 71)).first();

往find函數中“傳遞”一個eq函數,得到i爲71的數據。

過濾條件函數
|條件|函數|例子 |
|----|----|---|
|等於 |eq()| eq("i",50)|
|大於 |gt()| gt("i",50)|
|小於 |lt()| lt("i",50)|
|大於等於(>=)|gte()| gte("i",50)|
|小於等於(<=) |lte()| lte("i",50)|
|存在 |exists()| exists("i")|

排序操作

對FindIterable對象使用sort函數進行排序。ascending函數表示升序,descending函數表示降序。

collection.find().sort(orderBy(ascending("x", "y"), descending("z")))

過濾字段

有時候,我們並不需要一條數據中所有的內容,只是需要一部分而已,mongoDB 提供了一個projection方法,解決了這個問題。

collection.find().projection(fields(include("x", "y"), excludeId()))

使用forEach

有時候對不同的集合會有相同的操作,做通用方法是最佳實踐,Mongo對於函數式的編程範式真是充滿了熱情,爲我們提供了大量非常“函數式”的方法(在Java這種完全面向對象的語言裏,做到這樣真是不容易)。

我們可以通過forEach函數和Block類完成對集合中每個節點數據的操作。

Block<Document> printBlock = new Block<Document>() {
     @Override
     public void apply(final Document document) {
         System.out.println(document.toJson());
     }
};
collection.find(gt("i", 50)).forEach(printBlock);

更新數據

使用updateOne()函數,更新一條數據,第一個參數選取需要被更新的記錄,第二個參數設置需要被更新的具體數據

collection.updateOne(eq("i", 10), new Document("$set", new Document("i", 110)));

如果需要更新多條數據,可以使用updateMany函數,這個函數會返回一個UpdateResult類的對象,這個對象裏面保存了數據更新的結果。

UpdateResult updateResult = collection.updateMany(lt("i", 100),
          new Document("$inc", new Document("i", 100)));

刪除數據

通過集合使用deleteOne()方法來刪除指定的數據,如果想要刪除多條數據,使用deleteMany方法來完成操作.

collection.deleteOne(eq("i", 110));

DeleteResult deleteResult = collection.deleteMany(gte("i", 100));

Bulk操作

MongoDB提供了一種稱爲Bulk的操作方式,數據不會被立即被持久化到數據庫中,而是等待程序調度,確定合適的時間持久化到數據庫中。

Bulk操作支持有序操作,和無序操作兩種模式。有序操作中數據的的操作,會按照順序操作,一旦發生錯誤,操作就會終止;而無序操作,則不安順序執行,只會報告哪些操作發生了錯誤。

Bulk操作支持增刪改三種操作,對應的model分別是InsertOneModel、UpdateOneModel、DeleteOneModel、ReplaceOneModel。它們都繼承於WriteModel

// 有序操作
collection.bulkWrite(
  Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                new InsertOneModel<>(new Document("_id", 5)),
                new InsertOneModel<>(new Document("_id", 6)),
                new UpdateOneModel<>(new Document("_id", 1),
                                     new Document("$set", new Document("x", 2))),
                new DeleteOneModel<>(new Document("_id", 2)),
                new ReplaceOneModel<>(new Document("_id", 3),
                                      new Document("_id", 3).append("x", 4))));


 // 無序操作
collection.bulkWrite(
  Arrays.asList(new InsertOneModel<>(new Document("_id", 4)),
                new InsertOneModel<>(new Document("_id", 5)),
                new InsertOneModel<>(new Document("_id", 6)),
                new UpdateOneModel<>(new Document("_id", 1),
                                     new Document("$set", new Document("x", 2))),
                new DeleteOneModel<>(new Document("_id", 2)),
                new ReplaceOneModel<>(new Document("_id", 3),
                                      new Document("_id", 3).append("x", 4))),
  new BulkWriteOptions().ordered(false));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章