前几天,趁着有空,做了一个小的todolist应用,顺便也复习了一下纯servlet的开发,另外也学习了java操作mongodb的相关操作。

mongodb相信大家都或多或少听说过,没听说过的要好好反省啦,哈哈。它是一个nosql数据库。所谓的nosql肯定是跟RDBMS相对来说的,原来的RDBMS是有固定的格式的,这里说的格式是指固定的字段,数据库中没有的字段,你不可能插入,并且在某种情况下,不插入某些需要的值也会报错(mongodb应该也可以设必填的,这个由于是初入,暂时不讨论,接下来会有文章会讨论)。而nosql不需要这样,你可以随便指定一些原来你没插入的字段,只要是gson或者bson即可。

假如,有这样一句SQL:

insert into people(name,age) values('shun', 27);

这里前提假设我这个表只有两个字段,name和age。

接下来我执行这样的SQL:

insert into people('shun',27,28)

这里第三个值是我随便弄的,这时SQL就会报错,具体的错这里不纠结了,反正各个数据库的提示语不一样,但大致都是说字段数超出了。

而如果我们用nosql,就可以弄这样的json:

{"name":"shun","age":27,"noExist":28}

不管你想要多少字段都可以,你下次可以用这样的json:

{"name":"shun","age":27}

完全没有问题。

如果你之前没有了解过mongodb,可以到这里看看,这是官方的入门文档,写得清晰明了。

PS:之前有一篇文章吐槽mongodb的,可以到这里看看,10gen的CTO一一回答了那些问题,可以学到蛮多。

下面进入正题:

要用它,当然就先去下载啦,我这里使用的是2.6.1,版本不是最新的。最新的可以到这里下载,请根据自己的系统选择合适的版本,各个版本之间的差别不算太大(跨度大的除外,如1.x和2.x的区别),建议下载最新的。

之后再下载mongodb的java driver,可以到这里下载,不多说,还是直接最新的。实际上,这一步是可以省略的,我们这个例子这里使用maven,但为了自己使用,建议还是下下来,方便以后使用。

来,相信很多人等不及了,进入代码阶段啦。

首先肯定来maven文件啦(pom.xml):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>mongodb-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>2.12.2</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.2.4</version>
        </dependency>
    </dependencies>
</project>

随便找一个支持maven的IDE(eclipse,idea,netbeans)就行了,包会自动下载,包不大,很快的,gson是为了方便我们直接打印对象,你可以不用。

public static void main(String[] args) throws UnknownHostException {
    MongoClient mongoClient = new MongoClient();
    DB db = mongoClient.getDB("mongo-test");
    DBCollection collection = db.getCollection("test");

    //remove all
    collection.remove(new BasicDBObject());
    //process find
    DBCursor cursor = collection.find();
    System.out.println("before save");
    while(cursor.hasNext()) {
        System.out.println(new Gson().toJson(cursor.next()));
    }

    //process save
    DBObject object = new BasicDBObject();
    object.put("name", "shun");
    object.put("age", 27);
    collection.save(object);

    cursor = collection.find();
    System.out.println("after save");
    DBObject existObject = null;
    while(cursor.hasNext()) {
        existObject = cursor.next();
        System.out.println(new Gson().toJson(existObject));
    }


    //process delete
    String id = existObject.get("_id").toString();
    object = new BasicDBObject();
    //remember to change to new ObjectId,otherwise nothing happen after delete
    object.put("_id", new ObjectId(id));
    collection.remove(object);

    System.out.println("after delete");
    cursor = collection.find();
    while(cursor.hasNext()) {
        System.out.println(new Gson().toJson(cursor.next()));
    }

    //process complicated query
    object = new BasicDBObject();
    object.put("name","shun");
    object.put("age", 27);
    collection.save(object);

    object = new BasicDBObject();
    DBObject object1 = new BasicDBObject();
    object1.put("name", "shun");
    DBObject object2 = new BasicDBObject();
    object2.put("age", 27);
    object.put("$and", Arrays.asList(object1, object2));

    System.out.println("Complicated find");
    cursor = collection.find(object);
    while(cursor.hasNext()) {
        System.out.println(new Gson().toJson(cursor.next()));
    }
}

直接上代码是最好的方式。

我们一个个来看,首先我们在开始的部分先获取连接,这个相信都看得懂,最主要在这句:

DB db = mongoClient.getDB("mongo-test");

在mongoClient获取时连接实际上还没建立,只在获取DB的时候才会正式去建立连接。

而接下来,我们做了一个清空list的操作,remove(new BasicDBObject()),这里我们带了一个空的DBObject,这表明删除所有,这里要谨慎操作,并不要在生产环境这样做。接下来的查询所有,保存和删除应该都问题不大,这里大家看看就行了。

主要需要提醒的在这里:

mongodb和hibernate一样,提供了一个类似saveOrUpdate的方法,由内部去决定是否更新,mongodb是叫save,还有另外一个方法叫insert,这个并不会检查是否存在,只会插入一条记录,请根据需要选择全适的方法。

另,如果需要根据自动生成的_id进行删除时,请记住使用ObjectId类型,mongodb中有带bson的该类型,至于为什么要用它,待有兴趣的朋友去深入了解。

也许很多人感兴趣的地方会在怎么进行复杂的搜索上面,实际上它跟SQL非常类型,只是它的每个条件是一个DBOBject,而多个条件拼成DBObjectList。 如:

object = new BasicDBObject();
DBObject object1 = new BasicDBObject();
object1.put("name", "shun");
DBObject object2 = new BasicDBObject();
object2.put("age", 27);
object.put("$and", Arrays.asList(object1, object2));

这段代码所示,我们通过DBObject列表拼到类似SQL的where条件部分,最终的查询语句会是:

{"$and":[{"name":"shun"},{"age":27}]}

假设我们是需要查到大于等于27岁的用户,那么可以有

object2.put("age", new DBBasicObject("$gte", 27));

那么这时生成的query语句就会是:

{"$and":[{"name":"shun"},{"age":{"$gte":27}}]}

其实明白了每一个条件都是一个DBObject,理解起来就方便多了。

那么,今天这个小的入门就到这里,深入的就等接下来慢慢做罗。