MongoDB框架Jongo的使用介紹

1、Jongo可以用來做什麼?
 
Jongo框架的目的是使在MongoDB中可以直接使用的查詢Shell可以直接在Java中使用。在官網首頁有一個非常簡潔的例子:
 
SHELL:這種查詢方式是MongoDB數據庫支持的查詢方式。
JAVA DRIVER:是MongoDB Java驅動API中提供的查詢方式
JONGO:就是jongo框架提供的查詢方式。
 
由此可以看出,JONGO框架的意圖很明顯。
 
2、Jongo的下載
 
    關於MongoDB的安裝在此不作贅述,大家可以去它的官網上查看,介紹的非常詳細了,http://docs.mongodb.org/manual/installation/
 
    在Jongo的官網上,介紹說jongo框架的使用依賴於 Jackson 2.2.3, Bson4Jackson 2.2.3 and Mongo Java Driver 2.11+,而jongo目前最新的版本爲1.0。通過我的嘗試,我發現在實際應用中需要用到以下jar包:
bson4jackson-2.3.1.jar
jackson-annotations-2.4.1.jar
jackson-core-2.4.1.1.jar
jackson-databind-2.4.1.2.jar
jongo-1.0.jar
mongo-java-driver-2.12.2.jar
這些jar包都可以在Maven倉庫中找到,http://mvnrepository.com/
 
Jongo官網:http://jongo.org/
 
3、Jongo的使用
 
PersonInfo類:
 1 package com.jongo.enties;
 2  
 3 public class PersonInfo {
 4  
 5  private int id;
 6  private String person_name;
 7  private String sex;
 8  private String relationship;
 9  
10  public PersonInfo() {
11  
12  }
13 //getter and setter
14  @Override
15  public String toString() {
16   return "PersonInfo [id=" + id + ", person_name=" + person_name
17     + ", sex=" + sex + ", relationship=" + relationship + "]";
18  }
19 } 
1)第一個簡單的例子
package com.jongo.demo;
 
import java.util.Iterator;
 
import org.jongo.Jongo;
import org.jongo.MongoCollection;
 
import com.jongo.enties.PersonInfo;
import com.mongodb.DB;
import com.mongodb.MongoClient;
 
public class FirstDemo {
 
 public static void main(String[] args) {
 
  MongoClient mongo = null;
  try {
   mongo = new MongoClient("localhost",27017);
   DB db = mongo.getDB("jongo");
   Jongo jongo = new Jongo(db);
   
   MongoCollection person_info = jongo.getCollection("person_info");
   
   @SuppressWarnings("unchecked")
   Iterator<PersonInfo> all = (Iterator<PersonInfo>) person_info.find().as(PersonInfo.class);
   while(all.hasNext()) {
    PersonInfo personInfo = all.next();
    System.out.println("all:"+personInfo);
   }
   
   PersonInfo one = (PersonInfo) person_info.findOne("{id:1}").as(PersonInfo.class);
   System.out.println("one:"+one);
   
  } catch(Exception e) {
   e.printStackTrace();
  } finally {
   if(mongo != null) {
    mongo.close();
   }
  }
 }
}
運行結果:
all:PersonInfo [id=1, person_name=xiaoming, sex=Man, relationship=Friend]
all:PersonInfo [id=2, person_name=xiaohong, sex=Male, relationship=Friend]
one:PersonInfo [id=1, person_name=xiaoming, sex=Man, relationship=Friend]
 
2)Jongo的Save
  PersonInfo personInfo = new PersonInfo(4,"Marry","Male","ClassMate");
  mcoll.save(personInfo);
 
3)Jongo的Update
在Jongo中,Update語法和Mongo Shell有一點點不同,修改的查詢語句需要通過使用with()來實現,with()內可以包含一個字符串,或者是一個對象。
 
(1)person_info.update(new ObjectId("53cb7d99b963ac657273328c")).with("{$inc: {id: 2}}");
 
原始記錄:{ "_id" : ObjectId("53cb7d99b963ac657273328c"), "id" : 6, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate" }
更新後:{ "_id" : ObjectId("53cb7d99b963ac657273328c"), "id" : 8, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate" }
 
(2)person_info.update("{person_name : 'Dark'}").with("{$set:{person_name:'Dark Update'}}");
 
原始記錄:{ "_id" : ObjectId("53cb7d91b963ac657273328a"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate" }
更新後:{ "_id" : ObjectId("53cb7d91b963ac657273328a"), "id" : 5, "person_name" : "Dark Update", "sex" : "Male", "relationship" : "ClassMate" }
 
這種Update方式只會改變第一個被找到的記錄。而下面這種方式將會更新所有person_name爲Dark的記錄:
person_info.update("{person_name : 'Dark'}").multi().with("{$set:{person_name:'Dark Update'}}");
 
(3)person_info.update("{person_name : 'Dark'}").with(new PersonInfo(10, "Dark Update Object", "Man", "ClassMate"));
 
原始記錄:{ "_id" : ObjectId("53cb82ebb963ac657273329d"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate" }
更新後:{ "_id" : ObjectId("53cb82ebb963ac657273329d"), "id" : 10, "person_name" : "Dark Update Object", "sex" : "Man", "relationship" : "ClassMate" }
 
(4)person_info.update("{person_name : 'Dark'}").with("{$set:{address:#}}",new Address("0755","shenzhen"));
 
原始記錄:{ "_id" : ObjectId("53cb8310b963ac657273329e"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate" }
更新後:{ "_id" : ObjectId("53cb8310b963ac657273329e"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate", "address" : { "regionI d" : "0755", "provinceName" : "shenzhen" } }
 
4)Jongo的Insert
(1)person_info.insert("{person_name:'Insert Demo'}");
結果:{ "_id" : ObjectId("53cb85cf2fd87f4058d1ff93"), "person_name" : "Insert Demo" }
 
(2)插入一條記錄
PersonInfo personInfo = new PersonInfo(6,"Marry Insert","Male","ClassMate");
person_info.insert(personInfo);
結果:{ "_id" : ObjectId("53cb85e0b963ac65727332a3"), "id" : 6, "person_name" : "Marry Insert", "sex" : "Male", "relationship" : "ClassMate" }
 
(3)插入多條記錄:
PersonInfo personInfo2 = new PersonInfo(7,"Marry Insert2","Male","ClassMate");
person_info.insert(personInfo,personInfo2); //方式一
person_info.insert(new Object[]{personInfo,personInfo2});//方式二
 
5)Jongo的Remove
  person_info.remove(); //刪除所有
  person_info.remove(new ObjectId("53cb87c02fd8f9ffd258ceb3"));
  person_info.remove("{person_name:'Marry Insert'}");
 
6)Jongo的Query
在Jongo中,Query和Mongo Shell中的Query幾乎是一致的。
我們先來看看在Mongo Shell中如何查詢:
原始記錄:{ "_id" : ObjectId("53cb8e8a2602b31118434306"), "id" : 2, "person_name" : "xiaohong", "sex" : "Male", "relationship" : "Friend" }
//對於數字類型
> db.person_info.find({id:2});
或者> db.person_info.find({"id":2});
{ "_id" : ObjectId("53cb8e8a2602b31118434306"), "id" : 2, "person_name" : "xiaohong", "sex" : "Male", "relationship" : "Friend" }
//對於字符串類型
> db.person_info.find({person_name:'xiaohong'});  
或者> db.person_info.find({"person_name":"xiaohong"});
{ "_id" : ObjectId("53cb8e8a2602b31118434306"), "id" : 2, "person_name" : "xiaohong", "sex" : "Male", "relationship" : "Friend" }
 
那麼,在Jongo中怎麼查詢呢?其實,在上面的第一個簡單例子中我們已經見識過了,
Iterator<PersonInfo> all = (Iterator<PersonInfo>) person_info.find().as(PersonInfo.class);
PersonInfo one = (PersonInfo) person_info.findOne("{id:1}").as(PersonInfo.class);
 
我們再來看看這種文檔結構:{ "_id" : ObjectId("53cb9015b963ac65727332a4"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate", "address" : { "regionI
d" : "0755", "provinceName" : "shenzhen" } },假如我要查詢出address中regionId爲0755的記錄,該怎麼做?
 
在Mongo Shell中,我們是這樣查詢的:db.person_info.find({"address.regionId":"0755"});或者db.person_info.find({'address.regionId':'0755'});
 
在Jongo中的做法也是如出一轍,
PersonInfo personInfo =  (PersonInfo) person_info.findOne("{address.regionId:'0755'}").as(PersonInfo.class);
 
7)Jongo如何查詢出指定字段(不查詢某字段)?
我們一般通過{field:1}或{field:0}來控制查詢字段的顯示與否。
 
在Mongo Shell中,做法如下:
> db.person_info.find({},{person_name:1,_id:0}); //查詢出person_name,不查詢出_id。
{ "person_name" : "xiaohong" }
{ "person_name" : "Dark" }
 
而在Jongo中我們需要使用projection來到達這種效果。
  PersonInfo personInfo =
    (PersonInfo) person_info.findOne().projection("{person_name:1,id:1}").as(PersonInfo.class);
 
8)Jongo的Sort、Skip、Limit、Hint、Count
在Jongo中Sort、Skip、Limit、Hint、Count基本和Mongo Shell一致。
假設數據集合中有這樣兩天記錄:
> db.person_info.find()
{ "_id" : ObjectId("53cb8e8a2602b31118434306"), "id" : 2, "person_name" : "xiaohong", "sex" : "Male", "relationship" : "Friend" }
{ "_id" : ObjectId("53cb9015b963ac65727332a4"), "id" : 5, "person_name" : "Dark", "sex" : "Male", "relationship" : "ClassMate", "address" : { "regionI
d" : "0755", "provinceName" : "shenzhen" } }
 
Iterator<PersonInfo> sort = (Iterator<PersonInfo>) person_info.find().sort("{id:1}").as(PersonInfo.class);//sort {field:1} 升序,{field:-1} 降序
 
Iterator<PersonInfo> skip = (Iterator<PersonInfo>) person_info.find().skip(1).as(PersonInfo.class);//查詢時跳過多少條記錄
 
Iterator<PersonInfo> limit = (Iterator<PersonInfo>) person_info.find().limit(2).as(PersonInfo.class);//查詢指定數量的記錄
 
Iterator<PersonInfo> hint = (Iterator<PersonInfo>) person_info.find().hint("{person_name:-1}").as(PersonInfo.class);//在查詢過程中強制使用hint指定的索引方式,注意必須事先建立person_name字段的倒序索引。
 
long len = person_info.count("{id:5}");//查詢滿足條件的記錄數
9)Jongo的Oid
在映射部分,_id的定義可有註解@ObjectId來控制,如果你想完全地避免使用原先驅動包的ObjectId,可以使用Jongo提供的Oid類。其用法如下:
import static org.jongo.Oid.withOid;
PersonInfo personInfo
= new PersonInfo(); // @ObjectId String _id PersonInfo類中需要定義一個名爲_id的字段,且加上@ObjectId註解 person_info.save(personInfo); person_info.find(withOid(personInfo._id)).as(PersonInfo .class); // instead of new ObjectId(personInfo._id)
10)Jongo的查詢模板
幾乎所有查詢Jongo可以模板化:添加錨#。綁定參數可以BSON原語或任何複雜類型。
PersonInfo personInfo = person_info.findOne("{id:#,person_name:#}",2,"xiaohong").as(PersonInfo.class); //相當於findOne("{id:2,person_name:'xiaohong'}")
 
PersonInfo personInfo2 = person_info.findOne("{address:#}",new Address("0755","shenzhen")).as(PersonInfo.class); //相當於 db.person_info.findOne({'address.regionId':'0755','address.privinceName':'shenzhen'});
 
Iterator<PersonInfo> ite =  (Iterator<PersonInfo>) person_info.find("{id:{$in:#}}",ids).as(PersonInfo.class); //相當於db.person_info.find({id:{$in:[2,5]}});
11)Jongo的正則查詢
以下幾種正則查詢都是等價的:
 
  PersonInfo personInfo1 =
    person_info.findOne("{person_name:{$regex:#}}","Dar.*").as(PersonInfo.class);
 
  PersonInfo personInfo2 =
    person_info.findOne("{person_name:{$regex:'Dar.*'}}").as(PersonInfo.class);
 
  PersonInfo personInfo3 =
    person_info.findOne("{person_name:#}",Pattern.compile("Dar.*")).as(PersonInfo.class);
 
  Pattern p = Pattern.compile("Dar.*");
  PersonInfo personInfo4 =
    person_info.findOne("{person_name:{$regex:'"+p+"'}}").as(PersonInfo.class);
12)Jongo的聚合操作
 
(1)Distinct
List<String> personNames = person_info.distinct("person_name").as(String.class);
List<Address> addresses = person_info.distinct("address").query("{id:5}").as(Address.class);
int size = person_info.distinct("address").query("{id:5}").as(Address.class).size();
 
(2)聚合框架
這個特性只能在Mongo2.2以上版本中使用,所有諸如$project, $match, $limit, $skip, $unwind, $group, $sort的聚合操作都支持。在官網有一個例子:
collection.aggregate("{$project:{sender:1}}")
          .and("{$match:{tags:'read'}}")
          .and("{$limit:10}")
          .as(Email.class);
4、對象映射
      查詢結果自動映射到對象,它依賴於Jackson,涉及文檔結構,處理列表以及忽略缺失的屬性。僅僅需要一個無參構造器(甚至私有構造器都行,前提是對象是不可變的,註解@JsonCreator可以用來替代)
      _id在每個MongoDB文檔中是一個唯一的標識符,如果沒有被設定,它將自動生成,用Jongo來定義它時,一個屬性需要被命名爲_id或者帶有@Id註解(別名 @JsonProperty("_id")),可以使用專門的ObjectId類或者一個簡單的由@ObjectId註解的簡單字符串來定義。
        需要注意的是,當你保存一個自定義的文檔_id時(任何Java類型,除了數組意外,只要它是唯一值)總是需要在持久化之前手動的去進行設置。
        以下幾種情形式需要手動設置_id的:
   
        而下面這幾種是自動生成的:
   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章