Jongo

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

懒得翻译了。有兴趣的可以了解一下。
官网: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
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值