Jongo

来源:互联网 发布:c 九九乘法表代码 VB 编辑:程序博客网 时间:2024/05/02 05:03

转自:http://www.tuicool.com/articles/uIbuMz

懒得翻译了。有兴趣的可以了解一下。
jar包下载地址:http://download.csdn.net/detail/jiangxuchen/5075182
官网:http://jongo.org

Mongo with its shell

Mongo stores its datas into BSON documents, an attribute:value tree ( value can be simple, array or embedded object ). Documents are stored into collections, collections into databases. Mongo is schemaless, documents of a same collection don’t have to have the same attributes, they can be completely different.

The following commands add two documents into the friends collection. This collection is automatically created if it does not exist.

> db.friends.save({name:'Joe', age:17, address: {city:'Paris', zip:75018})> db.friends.save({name:'Jack', age:19, address: {city:'New York', street:'22 Madison Ave'})

Once created, the collection can be requested through numerous operators ( greater than, not empty, etc ). Those requests can be on every attributes, even sub nodes.

> db.friends.find()[  {name:'Joe', age:17, address: {city:'Paris', zip:75018},  {name:'Jack', age:19, address: {city:'New York', street:'22 Madison Ave'}] > db.friends.findOne({age: {$gt: 18}}){name:'Jack', age:19, address: {city:'New York', street:'22 Madison Ave'} > db.friends.find({'address.zip':{$exists:true}, 'address.city':'Paris'})[  {name:'Joe', age:17, address: {city:'Paris', zip:75018}]

The online Mongo documentation lists all the available operators. It also explain how to install Mongo in seconds.

We will use two classes, Friend and Address, to manipulate and store data into Mongo in Java. Those classes will be used without modification by the Java driver and Jongo. Their attributes are privates; constructors with arguments are not shown here for brevity’s sake.

public class Friend {  private String name;  private int age;  private Address address;   Friend() {}  // constructor with attributes here} public class Address {  private String city;  private Integer zip;  private String street;   Address() {}  // constructor with attributes here}

Jongo get access to Mongo with its Java driver and relies upon the Jacksonmarshalling library — well known for its performance — to offer the comfortable Mongo shell experience in Java. The following test initiate a connection to the xebia base, and then to the friends collection; every document of this collection is removed after each test.

public class JongoTest {  MongoCollection collection;   @Before  public void setUp() throws Exception {    Mongo mongo = new Mongo("127.0.0.1", 27017);    DB db = mongo.getDB("xebia");     Jongo jongo = new Jongo(db);    collection = jongo.getCollection("friends");  }   @After  public void tearDown() {    collection.drop();  }}

Once initialized, the MongoCollection class representing the friends collection, allows to directly save Java objects.

public class JongoTest {  @Before  public void setUp() throws Exception {    collection.save(new Friend("Joe", 17, new Address("Paris", 75000)));    collection.save(new Friend("Jack", 19, new Address("New York", "22 Madison Ave")));  }   @Test  public void findAll() throws Exception {    Iterable<Friend> friends = collection.find().as(Friend.class);    assertThat(friends).hasSize(2);  }}

Once documents are created — no surprises — requests are the same as in the shell. Then, the as(Class) method define the type into which the results have to be converted ( the class must have a no-args constructor — even private ). Results missing attributes are left to null, result attributes not in the object are ignored ( huge collection can be managed with tiny objects that way ).

With our previous requests, it becomes the following.

public class JongoTest {  @Test  public void findOver18() throws Exception {    Friend jack = collection.findOne("{age: {$gt: 18}}").as(Friend.class);     assertThat(jack.getName()).isEqualTo("Jack");    assertThat(jack.getAddress().getZip()).isNull();    assertThat(jack.getAddress().getStreet()).isEqualTo("22 Madison Ave");    // [...] other asserts  }   @Test  public void findInParis18() throws Exception {    Iterable<Friend> friends =      collection.find("{'address.zip':{$exists:true},'address.city':'Paris'}")        .as(Friend.class);     Friend joe = friends.iterator().next();    assertThat(joe.getName()).isEqualTo("Joe");    assertThat(joe.getAddress().getZip()).isEqualTo(75000);    assertThat(joe.getAddress().getStreet()).isNull();    assertThat(friends.iterator().hasNext()).isFalse();    // [...] other asserts  }}

Jongo offers the vast majority of Mongo operations — save, update, insert, remove, count, sort, distinct — and tries, for every one of them, to be as faithfully as possible to the Mongo shell spirit. The following tests give an insight.

public class JongoTest {  @Test  public void sort() throws Exception {    Iterable<Friend> friends = collection.find().sort("{name: -1}").as(Friend.class);    assertThat(friends).onProperty("name").containsExactly("Joe", "Jack");  }   @Test  public void distinct() {    List<Address> addresses = collection.distinct("address").as(Address.class);    assertThat(addresses).onProperty("city").contains("Paris", "New York");  }   @Test  public void count() {    long count = collection.count("{name: 'Joe'}");    assertThat(count).isEqualTo(1);  }   @Test  public void crud() {    Friend joe = collection.findOne("{name: 'Joe'}").as(Friend.class);    assertThat(joe.getAge()).isEqualTo(17);     collection.update("{name: 'Joe'}").with("{$inc: {age: 1}}");    joe = collection.findOne("{name: 'Joe'}").as(Friend.class);    assertThat(joe.getAge()).isEqualTo(18);     collection.remove("{name: 'Joe'}");    joe = collection.findOne("{name: 'Joe'}").as(Friend.class);    assertThat(joe).isNull();  }}

Jongo is available in the maven central repository.

<dependency>  <groupId>org.jongo</groupId>  <artifactId>jongo</artifactId>  <version>0.1</version></dependency>

Mongo with its Java driver

The best way to introduce the reasons behind Jongo is to not use it; let’s see how to use Mongo directly with its Java driver.

public class MongoJavaDriverTest {  DBCollection friends;   @Before  public void setUp() throws Exception {    Mongo mongo = new Mongo("127.0.0.1", 27017);    friends = mongo.getDB("xebia").getCollection("friends");  }   @After  public void tearDown() {    friends.drop();  }}

The driver do not offers to save Java objects; it requires a structure of BasicDBObject.

public class MongoJavaDriverTest {  @Before  public void setUp() throws Exception {    friends.save(newBasicDBObject("Joe", "Paris", ...));    friends.save(newBasicDBObject("Jack", "New York", ...));  }   private BasicDBObject newBasicDBObject(String name, String city, ...) {    BasicDBObject obj = new BasicDBObject();    obj.put("name", name);    obj.put("address", new BasicDBObject("city", city));    // [...] should adapt every field    return obj;  }   @Test  public void findAll() throws Exception {    DBCursor find = friends.find();    assertThat(find.size()).isEqualTo(2);  }}

The driver’s results are BasicDBObject too. Thus, it is necessary to adapt every fields to the corresponding Java attribute.

public class MongoJavaDriverTest {  @Test  public void findOver18() throws Exception {    DBObject findOne = friends.findOne(      QueryBuilder.start("age").greaterThan(18).get()    );     Friend jack = adaptDBObjectToFriend(findOne);    assertThat(jack.getName()).isEqualTo("Jack");    // [...] test every field  }   private Friend adaptDBObjectToFriend(DBObject dbFriend) {    String name = (String) dbFriend.get("name");    DBObject dbAddress = (DBObject) dbFriend.get("address");    Address address = new Address((String) dbAddress.get("city"), ...);    // [...] should adapt every field    return new Friend(name, age, address);  }}

At last, as shown in the previous example, requests have to be adapted too. The two initial requests, so concise, have to be rewritten with a QueryBuilder ( or using a BasicBBObject structure ) and looses their user-friendliness.

public class MongoJavaDriverTest {  @Test  public void findInParis18() throws Exception {    DBCursor find = friends.find(      QueryBuilder.start("address.zip").exists(true)        .and("address.city").is("Paris").get()    );     assertThat(find.size()).isEqualTo(1);     Friend joe = adaptDBObjectToFriend(find.next());    assertThat(joe.getName()).isEqualTo("Joe");    // [...] test every field  }}