[譯] MongoDB Java異步驅(qū)動(dòng)快速指南

導(dǎo)讀

mongodb-java-driver是mongodb的Java驅(qū)動(dòng)項(xiàng)目的畴。

本文是對(duì)MongoDB-java-driver官方文檔 MongoDB Async Driver Quick Tour 的翻譯(原創(chuàng)翻譯)。

mongodb-java-driver 從3.0版本開始同時(shí)支持同步耍共、異步方式(分別是不同的驅(qū)動(dòng)應(yīng)用)诡蜓。異步的好處熬甫,眾所周知,就是支持快速蔓罚、非阻塞式的IO操作,可以提高處理速度瞻颂。

請(qǐng)注意:本文僅介紹異步驅(qū)動(dòng)的使用指南豺谈。同步驅(qū)動(dòng)官方文檔:mongo-java-driver ,需要了解的朋友贡这,請(qǐng)移駕茬末。

安裝

簡(jiǎn)單提下安裝說明。

注:MongoDB 異步驅(qū)動(dòng)需要依賴Netty 或 Java 7盖矫。

如果你的項(xiàng)目是maven項(xiàng)目丽惭,只需在pom.xml中添加如下依賴:

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongodb-driver-async</artifactId>
        <version>3.3.0</version>
    </dependency>
</dependencies>

你也可以點(diǎn)擊鏈接直接下載jar包: 下載點(diǎn)這里

分割線辈双,下面是 MongoDB Async Driver Quick Tour 的譯文责掏。


MongoDB 異步驅(qū)動(dòng)快速指南

以下的代碼片段來自于 async driver source 的范例代碼 QuickTour.java

注意

如何安裝MongoDB異步驅(qū)動(dòng)請(qǐng)參考 安裝指導(dǎo) 湃望。

執(zhí)行異步回調(diào)

MongoDB異步驅(qū)動(dòng)利用Netty或Java7的AsynchronousSocketChannel 來提供一個(gè)支持異步的API换衬,以支持快速的、非阻塞式的IO操作证芭。

該API形式和MongoDB同步驅(qū)動(dòng)的新API保持一致瞳浦,但是任何會(huì)導(dǎo)致網(wǎng)絡(luò)IO的方法都會(huì)有一個(gè)SingleResponseCallback并且會(huì)立即返回,其中T是響應(yīng)對(duì)于該文檔的類型的任何方法废士。

SingleResponseCallback 回調(diào)接口需要實(shí)現(xiàn)一個(gè)簡(jiǎn)單方法onResult(T result, Throwable t) 叫潦,這個(gè)方法在操作完成時(shí)被調(diào)用。其中官硝,如果操作成功矗蕊, result參數(shù)包含著操作結(jié)果四敞;如果操作失敗,t中包含著拋出的異常信息拔妥。

重要

SingleResponseCallback的實(shí)現(xiàn)中檢查錯(cuò)誤并適當(dāng)處理錯(cuò)誤是十分重要的忿危。下面的錯(cuò)誤檢查僅為簡(jiǎn)便起見而省略。

創(chuàng)建一個(gè)連接

下面的例子展示多種方法去鏈接本地機(jī)器上的mydb數(shù)據(jù)庫没龙。詳情參考 MongoClients.create API手冊(cè)铺厨。

// 直接連接默認(rèn)服務(wù)host和端口,即 localhost:27017
MongoClient mongoClient = MongoClients.create();

// 使用一個(gè)字符串
MongoClient mongoClient = MongoClients.create("mongodb://localhost");

// 使用一個(gè)ConnectionString
MongoClient mongoClient = MongoClients.create(new ConnectionString("mongodb://localhost"));


// 使用MongoClientSettings
ClusterSettings clusterSettings = ClusterSettings.builder().hosts(asList(new ServerAddress("localhost"))).build();
MongoClientSettings settings = MongoClientSettings.builder().clusterSettings(clusterSettings).build();
MongoClient mongoClient = MongoClients.create(settings);

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

此時(shí)硬纤,database對(duì)象是一個(gè)MongoDB 服務(wù)器中指定數(shù)據(jù)庫的連接解滓。

注意

getDatabase("mydb") 方法并沒有回調(diào),因?yàn)樗鼪]有涉及網(wǎng)絡(luò)IO操作筝家。一個(gè) MongoDatabase 實(shí)例提供了與數(shù)據(jù)庫進(jìn)行交互的方法洼裤,若數(shù)據(jù)庫不存在,它會(huì)在插入數(shù)據(jù)時(shí)創(chuàng)建一個(gè)新的數(shù)據(jù)庫溪王。例如腮鞍,創(chuàng)建一個(gè) collection 或插入 document(這些確實(shí)需要回調(diào),因?yàn)樾枰婕熬W(wǎng)絡(luò)IO)莹菱。

MongoClient

MongoClient 實(shí)例實(shí)際上代表了一個(gè)數(shù)據(jù)庫的連接池移国;即使要并發(fā)執(zhí)行異步操作,你也僅僅需要一個(gè) MongoClient 實(shí)例道伟。

重要

一般情況下迹缀,在一個(gè)指定的數(shù)據(jù)庫集群中僅需要?jiǎng)?chuàng)建一個(gè)MongoClient實(shí)例,并通過你的應(yīng)用使用它蜜徽。

當(dāng)創(chuàng)建多個(gè)實(shí)例時(shí):

  • 所有的資源使用限制(例如最大連接數(shù))適用于每個(gè)MongoClient實(shí)例
  • 銷毀實(shí)例時(shí)祝懂,請(qǐng)確保調(diào)用 MongoClient.close() 清理資源。

獲得一個(gè) collection

要獲得一個(gè) collection 拘鞋,你需要在 getCollection(String collectionName) 方法中指定 collection 的名字:

下面的例子獲得名為 test 的collection :

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

添加一個(gè) document

一旦你有了collection對(duì)象砚蓬,你就可以向collection中插入document。例如掐禁,考慮如下的json形式document怜械;document中含包含了一個(gè)名為 info 的子document。

{
   "name" : "MongoDB",
   "type" : "database",
   "count" : 1,
   "info" : {
               x : 203,
               y : 102
             }
}

要?jiǎng)?chuàng)建document傅事,需要使用 Document 類缕允。你可以使用這個(gè)類來創(chuàng)建嵌入式的document。

Document doc = new Document("name", "MongoDB")
               .append("type", "database")
               .append("count", 1)
               .append("info", new Document("x", 203).append("y", 102));

要向 collection 中插入 document 蹭越,需要使用 insertOne() 方法障本。

collection.insertOne(doc, new SingleResultCallback<Void>() {
    @Override
    public void onResult(final Void result, final Throwable t) {
        System.out.println("Inserted!");
    }
});

SingleResponseCallback 是一個(gè) 函數(shù)式接口 并且它可以以lambda方式實(shí)現(xiàn)(前提是你的APP工作在JDK8):

collection.insertOne(doc, (Void result, final Throwable t) -> System.out.println("Inserted!"));

一旦document成功插入,onResult 回調(diào)方法會(huì)被調(diào)用并打印“Inserted!”。記住驾霜,在一個(gè)普通應(yīng)用中案训,你應(yīng)該總是檢查 t 變量中是否有錯(cuò)誤信息。

添加多個(gè) document

要添加多個(gè) documents粪糙,你可以使用 insertMany() 方法强霎。

接下來的例子會(huì)添多個(gè)document,document形式如下:

{ "i" : value }

循環(huán)創(chuàng)建多個(gè) documents 蓉冈。

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

要插入多個(gè) document 到 collection城舞,傳遞 documents 列表到 insertMany() 方法.

collection.insertMany(documents, new SingleResultCallback<Void>() {
    @Override
    public void onResult(final Void result, final Throwable t) {
        System.out.println("Documents inserted!");
    }
});

統(tǒng)計(jì)一個(gè) collection的document數(shù)量

既然前面的多個(gè)例子中我們已經(jīng)插入了 101 個(gè) document,我們可以檢查一下插入數(shù)量寞酿,使用 count() 方法家夺。下面的代碼應(yīng)該打印 101

collection.count(
  new SingleResultCallback<Long>() {
      @Override
      public void onResult(final Long count, final Throwable t) {
          System.out.println(count);
      }
  });

查詢 collection

使用 find() 方法來查詢 collection伐弹。

在一個(gè) collection 中找到第一個(gè) document

要獲得 collection 中的第一個(gè) document 拉馋,需要調(diào)用 first() 方法。collection.find().first() 返回第一個(gè) document 或 null 值惨好,而不是一個(gè)游標(biāo)煌茴。這種查詢適用于匹配一個(gè)單一的 document,,或你僅對(duì)第一個(gè) document 有興趣昧狮。

注意

有時(shí)你需要多次使用相同或相似的回調(diào)方法景馁。在這種情況下,合理的做法是DRY(不要重復(fù)自己):把回調(diào)保存為一個(gè)具體的類或分配給一個(gè)變量逗鸣。

SingleResultCallback<Document> printDocument = new SingleResultCallback<Document>() {
    @Override
    public void onResult(final Document document, final Throwable t) {
        System.out.println(document.toJson());
    }
};

下面的例子傳遞 printDocument 回調(diào)給 first 方法:

collection.find().first(printDocument);

范例會(huì)打印下面的 document:

{ "_id" : { "$oid" : "551582c558c7b4fbacf16735" },
  "name" : "MongoDB", "type" : "database", "count" : 1,
  "info" : { "x" : 203, "y" : 102 } }

注意

_id 元素會(huì)被MongoDB動(dòng)態(tài)的添加到你的 document 上,并且值也會(huì)與展示的不同绰精∪鲨担“_” 和 “$”開頭的域是MongoDB 預(yù)留給內(nèi)部使用的。

遍歷查找一個(gè)collection中所有的 document

要檢索 collection 中所有的 document笨使,需要使用 find() 方法卿樱。find() 方法返回一個(gè) FindIterable 實(shí)例,它提供了一個(gè)接口來鏈接和控制查找操作硫椰。使用 forEach() 方法可以提供一個(gè) Block 作用于每個(gè) document 并且迭代結(jié)束時(shí)執(zhí)行回調(diào)一次繁调。下面的代碼遍歷 collection 中所有的 document 并逐一打印,最后打印 “Operation Finished!”靶草。

Block<Document> printDocumentBlock = new Block<Document>() {
    @Override
    public void apply(final Document document) {
        System.out.println(document.toJson());
    }
};
SingleResultCallback<Void> callbackWhenFinished = new SingleResultCallback<Void>() {
    @Override
    public void onResult(final Void result, final Throwable t) {
        System.out.println("Operation Finished!");
    }
};

collection.find().forEach(printDocumentBlock, callbackWhenFinished);

通過查詢條件獲得一個(gè) document

我們可以創(chuàng)建一個(gè)過濾器傳遞給 find() 方法蹄胰,以獲得我們 collection 中的一組子集。例如奕翔,如果我們想查找 key為“i” 裕寨,value為71 的 document,我們要按下面的方法做(重用 printDocument 回調(diào))。

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

collection.find(eq("i", 71)).first(printDocument);

最終會(huì)只印一個(gè) document:

{ "_id" : { "$oid" : "5515836e58c7b4fbc756320b" }, "i" : 71 }

重要

請(qǐng)使用 Filters宾袜、Sorts捻艳、ProjectionsUpdates API手冊(cè)來找到簡(jiǎn)單、清晰的方法構(gòu)建查詢庆猫。

通過查詢獲得一組 documents

我們可以使用查詢來從我們的 collection 中獲得一組 document 集合认轨。例如,如果我們想獲得所有 key 為“i”月培,value 大于50 的 document 嘁字,我們應(yīng)該按下面方式做(重用 printDocumentBlock 阻塞和 callbackWhenFinished 回調(diào)):

// 使用范圍查詢獲取子集
collection.find(gt("i", 50)).forEach(printDocumentBlock, callbackWhenFinished);

范例應(yīng)該會(huì)打印所有 i > 50 的document。

我們也可以增加上限范圍节视,如 50 < i <= 100

collection.find(and(gt("i", 50), lte("i", 100))).forEach(printDocumentBlock, callbackWhenFinished);

document 排序

我們可以對(duì) document 進(jìn)行排序拳锚。通過在 FindIterable 上調(diào)用 sort() 方法,我們可以在一個(gè)查詢上進(jìn)行一次排序寻行。

下面的例子中霍掺,我們使用 exists() 和 降序排序 descending("i") 來為我們的 document 排序。

collection.find(exists("i")).sort(descending("i")).first(printDocument);

投射域

有時(shí)我們不需要將所有的數(shù)據(jù)都存在一個(gè) document 中拌蜘。Projections 可以用來為查詢操作構(gòu)建投射參數(shù)并限制返回的字段杆烁。

下面的例子中,我們會(huì)對(duì)collection進(jìn)行排序简卧,排除 _id 字段兔魂,并輸出第一個(gè)匹配的 document。

collection.find().projection(excludeId()).first(printDocument);

聚合

有時(shí)举娩,我們需要將存儲(chǔ)在 MongoDB 中的數(shù)據(jù)聚合析校。 Aggregates 支持對(duì)每種類型的聚合階段進(jìn)行構(gòu)建。

下面的例子铜涉,我們執(zhí)行一個(gè)兩步驟的轉(zhuǎn)換來計(jì)算 i * 10 的值智玻。首先我們使用 Aggregates.match 查找所有 i > 0 的document 。接著芙代,我們使用 Aggregates.project 結(jié)合 $multiply 操作來計(jì)算 “ITimes10” 的值吊奢。

collection.aggregate(asList(
    match(gt("i", 0)),
    project(Document.parse("{ITimes10: {$multiply: ['$i', 10]}}")))
).forEach(printDocumentBlock, callbackWhenFinished);

For $group operations use the Accumulators helper for any accumulator operations.

對(duì)于 $group 操作使用 Accumulators 來處理任何 累加操作

下面的例子中纹烹,我們使用 Aggregates.group 結(jié)合 Accumulators.sum 來累加所有 i 的和页滚。

collection.aggregate(singletonList(group(null, sum("total", "$i")))).first(printDocument);

注意

當(dāng)前,還沒有專門用于 聚合表達(dá)式 的工具類铺呵」郏可以使用 Document.parse() 來快速構(gòu)建來自于JSON的聚合表達(dá)式。

更新 document

MongoDB 支持許多的 更新操作 陪蜻。

要更新至多一個(gè) document (可能沒有匹配的document)邦马,使用 updateOne 方法指定過濾器并更新 document 。這里,我們使用 Updates.set 來更新匹配過濾器 i 等于 10 的第一個(gè) document 并設(shè)置 i 的值為 110滋将。

collection.updateOne(eq("i", 10), set("i", 110),
    new SingleResultCallback<UpdateResult>() {
        @Override
        public void onResult(final UpdateResult result, final Throwable t) {
            System.out.println(result.getModifiedCount());
        }
    });

使用 updateMany 方法可以更新所有匹配過濾器的 document 邻悬。這里我們使用 Updates.inc 來為所有 i 小于 100 的document 增加 100 。

collection.updateMany(lt("i", 100), inc("i", 100),
    new SingleResultCallback<UpdateResult>() {
        @Override
        public void onResult(final UpdateResult result, final Throwable t) {
            System.out.println(result.getModifiedCount());
        }
    });

更新方法返回一個(gè) UpdateResult随闽,其中包含了操作的信息(被修改的 document 的數(shù)量)父丰。

刪除 document

要?jiǎng)h除至多一個(gè) document (可能沒有匹配的document)可以使用 deleteOne 方法。

collection.deleteOne(eq("i", 110), new SingleResultCallback<DeleteResult>() {
    @Override
    public void onResult(final DeleteResult result, final Throwable t) {
        System.out.println(result.getDeletedCount());
    }
});

使用 deleteMany 方法可以刪除所有匹配過濾器的 document 掘宪。這里我們刪除所有 i 大于等于的 document蛾扇。

collection.deleteMany(gte("i", 100), new SingleResultCallback<DeleteResult>() {
    @Override
    public void onResult(final DeleteResult result, final Throwable t) {
        System.out.println(result.getDeletedCount());
    }
});

刪除方法返回一個(gè) DeleteResult,其中包含了操作的信息(被刪除的 document 的數(shù)量)魏滚。

批量操作

批量操作允許批量的執(zhí)行 插入镀首、更新、刪除操作鼠次。批量操作有兩種類型:

  1. 有序的批量操作

    有序的執(zhí)行所有操作并在第一個(gè)寫操作的錯(cuò)誤處報(bào)告錯(cuò)誤更哄。

  2. 無序的批量操作

    執(zhí)行所有的操作并報(bào)告任何錯(cuò)誤。

    無序的批量操作不保證執(zhí)行順序腥寇。

我們來圍觀一下兩個(gè)分別使用有序和無序操作的簡(jiǎn)單例子:

SingleResultCallback<BulkWriteResult> printBatchResult = new SingleResultCallback<BulkWriteResult>() {
    @Override
    public void onResult(final BulkWriteResult result, final Throwable t) {
        System.out.println(result);
    }
};

// 2. 有序批量操作
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))),
  printBatchResult
);


 // 2. 無序批量操作
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),
  printBatchResult
);

重要

不推薦在pre-2.6的MongoDB 服務(wù)器上使用 bulkWrite 方法成翩。因?yàn)檫@是第一個(gè)支持批量寫操作(插入、更新赦役、刪除)的服務(wù)器版本麻敌,它允許驅(qū)動(dòng)去實(shí)現(xiàn) BulkWriteResultBulkWriteException 的語義。這個(gè)方法雖然仍然可以在pre-2.6服務(wù)器上工作掂摔,但是性能不好术羔,一次只能執(zhí)行一個(gè)寫操作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乙漓,一起剝皮案震驚了整個(gè)濱河市聂示,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌簇秒,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秀鞭,死亡現(xiàn)場(chǎng)離奇詭異趋观,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锋边,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門皱坛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人豆巨,你說我怎么就攤上這事剩辟。” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵贩猎,是天一觀的道長(zhǎng)熊户。 經(jīng)常有香客問我,道長(zhǎng)吭服,這世上最難降的妖魔是什么嚷堡? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮艇棕,結(jié)果婚禮上蝌戒,老公的妹妹穿的比我還像新娘。我一直安慰自己沼琉,他們只是感情好北苟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著打瘪,像睡著了一般友鼻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瑟慈,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天桃移,我揣著相機(jī)與錄音,去河邊找鬼葛碧。 笑死借杰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的进泼。 我是一名探鬼主播蔗衡,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼乳绕!你這毒婦竟也來了绞惦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤洋措,失蹤者是張志新(化名)和其女友劉穎济蝉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菠发,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡王滤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了滓鸠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雁乡。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖糜俗,靈堂內(nèi)的尸體忽然破棺而出踱稍,到底是詐尸還是另有隱情曲饱,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布珠月,位于F島的核電站扩淀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏桥温。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一侵浸、第九天 我趴在偏房一處隱蔽的房頂上張望旺韭。 院中可真熱鬧,春花似錦掏觉、人聲如沸区端。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽织盼。三九已至,卻和暖如春酱塔,著一層夾襖步出監(jiān)牢的瞬間沥邻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工羊娃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唐全,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓蕊玷,卻偏偏與公主長(zhǎng)得像邮利,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子垃帅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法延届,類相關(guān)的語法,內(nèi)部類的語法贸诚,繼承相關(guān)的語法方庭,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 如何在 Windows 上安裝 MongoDBMongoDB C# Driver 管理快速入門指南 這是Mongo...
    陳弟CD閱讀 12,200評(píng)論 0 13
  • 第一步寫辭職信 這是必須也是最基本的一步,辭職信和應(yīng)聘信一樣媒怯,都應(yīng)有一定的格式,而一封合格的辭職信一般必須包括以下...
    小蟲子11閱讀 180評(píng)論 0 0
  • 2015最后一天 好多好多想說的話想對(duì)你說 可也不知道從何說起 也不知道你愿不愿意聽 慢慢的我接受了離別的事實(shí)...
    我們還會(huì)遇見閱讀 269評(píng)論 0 1
  • 花紅云起雀驚鳴髓窜,秋時(shí)奉來一喜欣扇苞。 舉首方知晴尚好欺殿,只是當(dāng)世不自知。
    寄清風(fēng)閱讀 258評(píng)論 0 2