4.1MongoDb介绍及java使用

什么是mongogb

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
来源 【百度百科

mongodb的特性与优点

  • 存储方式:虚拟内存+持久化。
  • 查询语句:是独特的Mongodb的查询方式。
  • 适合场景:事件的记录,内容管理或者博客平台等等。
  • 架构特点:可以通过副本集,以及分片来实现高可用。
  • 数据处理:数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存中,将数据存储在物理内存中,从而达到高速读写。
  • 成熟度与广泛度:新兴数据库,成熟度较低,Nosql数据库中最为接近关系型数据库,比较完善的DB之一,适用人群不断在增长。

优点:

  • 快速!在适量级的内存的Mongodb的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快。
  • 高扩展
  • 自身的Failover机制
  • json的存储格式

mongodb的具体应用场景

mongodb的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。mongo适用于以下场景:

  • 1、网站数据:mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • 2、缓存:由于性能很高,mongo也适合作为信息基础设施的缓存层。在系统重启之后,由mongo搭建的持久化缓存可以避免下层的数据源过载。
  • 3、大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
  • 4、高伸缩性的场景:mongo非常适合由数十或者数百台服务器组成的数据库。
  • 5、用于对象及JSON数据的存储:mongo的BSON数据格式非常适合文档格式化的存储及查询。
    不适合的场景:
  • 1、高度事务性的系统,比如银行、证券等强业务系统。
  • 2、传统的商业智能应用,比如BI查询分析,需要对多字段进行组合查询。
  • 3、需要SQL的场景,比如需要做sum、groupby 等汇总统计系统。

上面那些来源于mongodb的官方说明,简单来讲,就是需要快速、大量按唯一主键进行查询更新的,可以采用mongodb,需要多表关联查询、事务操作的,不适合mongodb

举几个例子:
1、ofo或膜拜单车等车辆的位置信息,数量有限(相对),而且可以根据车牌号进行快速查询,并需要实时更新位置信息,即LBS应用。
2、社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
3、铁路的车号追踪系统,实时查询每辆车的车种、车型、货物、当前站、当前位置等信息。
4、实时监控系统,监控服务器的访问数据、监控应用系统的请求计数等
5、网游中的玩家装备、积分、技能、经验等快速变换信息,方便查询、更新
6、物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来
7、物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
8、视频直播,使用 MongoDB 存储用户信息、礼物信息等

mongodb下载与安装

官网下载

分linux、windows、mac等,根据需要选择下载,生产还是建议linux,主从结构。

linux下安装:http://www.runoob.com/mongodb/mongodb-linux-install.html
windows下安装:http://www.runoob.com/mongodb/mongodb-window-install.html

界面化管理工具

mongodb的管理工具很多,这里介绍用的比较多的Robomongo

工具下载

安装完后打开:

Robomongo工具

建立连接,端口默认27017

连接后如图所示

mongodb在java中的使用

添加mongodb的依赖

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
     <version>3.4.2</version>
</dependency>
<dependency>
     <groupId>org.mongodb</groupId>
     <artifactId>bson</artifactId>
     <version>3.4.2</version>
</dependency>

这里面用到了两个,一个是mongodb的java驱动,一个mongodb的bson数据格式jar包

MongoConnect连接数据库

public class MongoConnect {

    /**
     * 建立mongodb连接
     *
     * @return
     */
    public MongoClient getConnection() {
        MongoClient mongoClient = null;
        try {
            //连接到MongoDB服务 如果是远程连接可以替换“localhost”为服务器所在IP地址
            //ServerAddress()两个参数分别为 服务器地址 和 端口
            ServerAddress serverAddress = new ServerAddress("localhost", 27017);
           /* List<ServerAddress> addrs = new ArrayList<ServerAddress>();
            addrs.add(serverAddress);//如果是集群,需要用到地址列表*/
            mongoClient = new MongoClient(serverAddress);
            /*
            //MongoCredential.createScramSha1Credential()三个参数分别为 用户名 数据库名称 密码
            MongoCredential credential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
            List<MongoCredential> credentials = new ArrayList<MongoCredential>();
            credentials.add(credential);

            //通过连接认证获取MongoDB连接
            mongoClient = new MongoClient(addrs, credentials);
            */
        } catch (Exception e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
        }
        return mongoClient;
    }

    /**
     * 关闭连接
     *
     * @param mongoClient
     */
    public void closeConnection(MongoClient mongoClient) {
        mongoClient.close();
    }

    public static void main(String[] args) {
        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();
        System.out.println(mongoClient);
        mongoConnect.closeConnection(mongoClient);
    }
}

这里要说明以下几点:
1、如果连接mongodb的集群,需要用到List<ServerAddress>,mongoClient连接多个地址
2、连接时如果mongodb没有账号和密码,则不需要设置MongoCredential直接连接即可。当然一定要确保mongodb处于内网,不被外网攻击。前一段时间出现的mongodb攻击,就是因为mongodb没有密码,同时27017端口开放了,导致数据信息泄露。

创建Collection和查询,MongoConnect.java

public class CreateCollection {
    public static void main(String[] args) {
        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();//建立mongb的客户端连接

        MongoDatabase mongoDatabase = mongoClient.getDatabase("test");//连接指定数据库test,如果不存在会创建
        System.out.println("连接数据库成功");
        //创建集合 参数为 “集合名称”
        mongoDatabase.createCollection("collectionTest");//创建集合
        System.out.println("集合创建成功");

        //获取集合 参数为“集合名称”
        MongoCollection<Document> mongoCollection = mongoDatabase.getCollection("collectionTest");//如果不存在会创建
        System.out.println("成功获取集合");
    }
}

说明以下几点:

1、mongoClient.getDatabase("test"); mongoClient在获取数据库时,如果该库不存在,会新建一个
2、mongodb中的database和关系数据库中的database非常相像,MongoCollection和关系数据库中的table类似。

插入文档,InsertDocument.java

public class InsertDocument {

    public static void main(String[] args) {
        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();//建立mongb的客户端连接
        MongoCollection<Document> mongoCollection = mongoClient.getDatabase("test").getCollection("collectionTest");//如果不存在会创建
        Document document = new Document("title", "MongoDB").
                append("description", "database").
                append("likes", 100).
                append("by", "Fly");
        List<Document> documents = new ArrayList<Document>();
        documents.add(document);
        mongoCollection.insertMany(documents);
        System.out.println("文档插入成功");
    }
}

这里面的Document就和关系数据库中的row类似,先建立一个Document,并设置具体的字段,这里面的字段就是按照keyvalue的形式创建的。然后获取mongoCollection,执行insert查询数据。

执行成功,用Robomongo查看如下:

查看新增记录

这里面的id字段是mongodb自动生成的字段

检索文档,SearchDocument.java

public class SearchDocument {

    public static void main(String[] args) {
        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();//建立mongb的客户端连接
        MongoCollection<Document> mongoCollection = mongoClient.getDatabase("test").getCollection("collectionTest");//如果不存在会创建
        //检索所有文档
        /**
         * 1. 获取迭代器FindIterable<Document>
         * 2. 获取游标MongoCursor<Document>
         * 3. 通过游标遍历检索出的文档集合
         * */
        FindIterable<Document> findIterable = mongoCollection.find();
        MongoCursor<Document> mongoCursor = findIterable.iterator();
        while(mongoCursor.hasNext()){
            System.out.println(mongoCursor.next());
        }
    }
}

原理就是,先确定mongoCollection即要检索哪个Collection,然后建立FindIterable迭代器,建立mongoCursor,就是JDBC中的ResultSet,循环输出。

当然Mongodb的查询还有很多很多,比如聚合查询、条件查询、or查询等等,后面会更加详细的介绍

更新Document,UpdateDocument.java

public class UpdateDocument {
    public static void main(String[] args) {

        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();//建立mongb的客户端连接
        MongoCollection<Document> mongoCollection = mongoClient.getDatabase("test").getCollection("collectionTest");//如果不存在会创建

        //更新文档   将文档中likes=100的文档修改为likes=200
        mongoCollection.updateMany(Filters.eq("likes", 100), new Document("$set", new Document("likes", 200)));
        //检索查看结果
        FindIterable<Document> findIterable = mongoCollection.find();
        MongoCursor<Document> mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            System.out.println(mongoCursor.next());
        }
    }
}

mongoCollection.updateMany(Filters.eq("likes", 100), new Document("$set", new Document("likes", 200)));这句话,先查找对应记录,然后更新对应字段。

删除Document,DeleteDocument.java

public class DeleteDocument {
    public static void main(String[] args) {
        MongoConnect mongoConnect = new MongoConnect();
        MongoClient mongoClient = mongoConnect.getConnection();//建立mongb的客户端连接
        MongoCollection<Document> mongoCollection = mongoClient.getDatabase("test").getCollection("collectionTest");//如果不存在会创建
        //删除符合条件的第一个文档
        mongoCollection.deleteOne(Filters.eq("likes", 200));
        //删除所有符合条件的文档
        mongoCollection.deleteMany (Filters.eq("likes", 200));
        //检索查看结果
        FindIterable<Document> findIterable = mongoCollection.find();
        MongoCursor<Document> mongoCursor = findIterable.iterator();
        while(mongoCursor.hasNext()){
            System.out.println(mongoCursor.next());
        }
    }
}

mongoCollection.deleteMany (Filters.eq("likes", 200));可以删除一条或多条,按照指定条件操作。

学习mongodb的时候,每个对象都参照关系数据库的对应对象,学习起来就会快很多了。各个对象的关联关系如下:

  • MongoConnect->Connection
  • MongoDatabase ->Database(MySql),User/Schema(Oracle)
  • Collection->Table
  • Document ->Row
  • FindIterable->PrepareStatement
  • FindIterable ->ResultSet

源码下载

本工程详细源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容