@[toc](MangoDB 学习笔记)

一、什么是 MangoDB?

1.1 MangoDB 介绍

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

百度百科介绍

从上面的描述可以得知

  • MangoDB 由 c++ 编写,运行效率自然不低
  • 分布式文件存储系统
  • 开源数据库系统,谁都可以用

1.2 MangoDB 的特点

这里只列举我认为是比较有用特点,网上关于 MangoDB 的特点介绍还有很多很多,我这里就不一一列举了。

  • MongoDB 是一个面向文档存储的数据库,操作起来比较简单和容易。
  • 文件存储格式为BSON(一种JSON的扩展),BSON 支持文档和数组的嵌套。
  • Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
  • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言
  • 等等

1.3 MangoDB 相关术语介绍

1.3.1 数据库

一个 mangoDB 可以建立多个数据库
MangoDB 的默认数据库是 “”db” ,该数据库存储在 data 目录中

1.3.2 文档(Document)

文档是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

下面就是一个简单的文档示例

  1. {"site": "https://www.gorit.cn", "name":"CodingGorit"}

RDBMS 与 MangoDB 对应的术语

RDBMS MangoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MangoDB 提供了 key 为 _id)

1.3.3 集合

集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。

集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

比如,我们可以将以下不同的数据结构的文档插入到集合中

  1. {"site": "https://www.gorit.cn"}
  2. {"site": "https://www.gorit.cn", "name":"CodingGorit"}
  3. {"site": "https://www.gorit.cn", "name":"CodingGorit","age":5}

当第一个文档插入时,集合就会被创建

  • 集合名不能使空字符串
  • 集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以”system.”开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$。

1.3.4 一览表

SQL 术语概念 MangoDB 术语概念 解释/说明
database database 数据库
table collection 数据库表/ 集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
primary key primary key 主键 MangoDB 自动将_id 字段设置为主键

1.4 MangoDB 数据类型

下面列举 MangoDB 中常见的数据类型 (摘自菜鸟教程)

数据类型 描述
String 字符串,存储数据的常用数据类,在 mangoDB 中 UTF-8 编码的字符串才是合法的
Integer 整型数值,用于存储数值,根据你所采取的服务器,可以为分 64位和 32位。
Boolean 布尔值,存储布尔值(真假)
Double 双精度浮点值,用于存储浮点值
Min、Max keys 讲一个值与 BSON (二进制 JSON) 元素的最低值和最高值相比
Array 用于将数组或者列表多个值存储为一个键
TimeStamp 时间戳,记录文档修改或者添加的具体时间
Object 用于内嵌文档
Null 用于创建空值
Date 日期时间,用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间,创建 Date 对象,传入年月日信息

。。

二、MangoDB 可以做什么?

我们看看网上的企业都在哪 mangoDB 做什么

  • Craiglist上使用MongoDB的存档数十亿条记录。
  • FourSquare,基于位置的社交网站,在Amazon EC2的服务器上使用MongoDB分享数据。
  • Shutterfly,以互联网为基础的社会和个人出版服务,使用MongoDB的各种持久性数据存储的要求。
  • bit.ly, 一个基于Web的网址缩短服务,使用MongoDB的存储自己的数据。
  • spike.com,一个MTV网络的联营公司, spike.com使用MongoDB的。
  • Intuit公司,一个为小企业和个人的软件和服务提供商,为小型企业使用MongoDB的跟踪用户的数据。
  • sourceforge.net,资源网站查找,创建和发布开源软件免费,使用MongoDB的后端存储。
  • etsy.com ,一个购买和出售手工制作物品网站,使用MongoDB。
    纽约时报,领先的在线新闻门户网站之一,使用MongoDB。
  • CERN,著名的粒子物理研究所,欧洲核子研究中心大型强子对撞机的数据使用MongoDB。

三、MangoDB 的基本使用

3.1 下载及配置 MangoDB

MangoDB 迅雷网盘
提取码:2JOq

MangoDB 百度云网盘
提取码:g9lu

具体安装的过程我就省略,网上有很多教程,我这里就不展示了

下载好安装完毕后,记得配置环境变量

  • D:\Program Files\mangoDB\bin

记得在根路径创建一个 data 文件夹,我们的数据文件都会存储在这里
6.2.2 MongoDB - 图1

3.2 MangoDB 常用命令一栏

3.2.1 数据库相关操作

mangoDB 命令 命令作用 执行效果
show dbs 显示所有数据的列表 xx01
db 显示当前数据库或者集合 xx02
use xxx (xxx 为数据库名) 可以连接到一个指定数据库,如果数据库不存在,就会创建数据库 xxx03
db.dropDatabase() 删除数据库,前提是要用 use xxx 进入该数据库,然后再删除 xxx04

3.2.2 集合操作

  1. 创建集合 | mangoDB 命令 | 命令作用 | 执行效果 | | —- | —- | —- | | db.createCollection(name, options) | 创建集合 | xxx01 | | show collections & show tables | 查看看集合 | xxx02 |

创建固定集合 mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个。

  1. db.createCollection("mycol", { capped : true, autoIndexId : true, size :
  2. 6142800, max : 10000 } )
  3. { "ok" : 1 }
  1. 删除集合
  • db.collection.drop()
  • collection 为集合名称

3.2.3 文档操作

1 插入文档
  1. show dbs; // 查看数据库
  2. use test; // 如果 test 数据库不存在,则创建 test
  3. // 插入一条记录,如果集合不存在,先创建集合,在插入数据
  4. db.user.insert({"id":"1","name":"Gorit","age":16});
  5. // 一次性插入多条记录
  6. db.user.insert({"id":"5","name":"Gorit555","age":16},{"id":"6","name":"Gorit6666","age":18});
  7. // 一次性插入多条
  8. db.user.insertMany([{"id":"4","name":"Gori333","age":16},{"id":"4","name":"Gorit4444","age":18}])

插入文档还有

  • db.collection_name.insertOne()
  • db.collection_name.insertMany()

2. 更新文档

语法

  1. db.collection.update(
  2. <query>,
  3. <update>,
  4. {
  5. upsert: <boolean>,
  6. multi: <boolean>,
  7. writeConcern: <document>
  8. }
  9. )

参数说明:

  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如$,$inc…)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
  • writeConcern :可选,抛出异常的级别。
  1. // 添加测试数据
  2. db.user.insert({"id":"5","name":"Gorit ","age":16},);
  3. // 修改数据
  4. db.user.update(
  5. {"name":"Gorit"},
  6. {$set:{"name":"张三","age":17}}
  7. );
  8. // 这样做只会修改第一条同名的条件记录,如果要批量修改同名的记录,可以这么做
  9. db.user.update(
  10. {"name":"Gorit"},
  11. {$set:{"name":"张三","age":17}},
  12. {multi:true}
  13. );
  14. // 更多的条件修改
  15. 只更新第一条记录:
  16. db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
  17. 全部更新:
  18. db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
  19. 只添加第一条:
  20. db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
  21. 全部添加进去:
  22. db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
  23. 全部更新:
  24. db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
  25. 只更新第一条记录:
  26. db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );

3. 删除文档
db.collection.remove(
   <query>,
   <justOne>
)

// mangoDB 版本在 2.6 版本以后
db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)

使用

// 删除所有数据
db.collection_ name.remove({})

// 删除指定字段的记录
db.collection_name.remove({"id":"1"})

// 删除指定记录的第一条
db.collection_name.remove({"id":"1"},1)

// 新版本删除所有的集合
db.collection_name.deleteMany({})

// 新版本删除多个 status 为 A的
db.collection_name.deleteMany({ status : "A" })

// 新版本删除一个 status 为 D 的集合
db.inventory.deleteOne( { status: "D" } )

4. 查询文档

4.1 条件查询

对应 where 条件查询

操作 格式 示例 RDBMS 中对应的语句
等于 { key:value } db.user.find({“name”:”Gorit111”}) where age = 17
小于 { key : { $lt : value } } db.user.find({“age”:{$lt:20}}); where age < 20
小于或等于 { key : { $lte : value } db.user.find({“age”:{$lte:20}}); where age <= 20
大于 { key : { $gt : value } db.user.find({“age”:{$gt:16}}); where age > 16
大于或等于 { key : { $gte : value } db.user.find({“age”:{$gte:16}}); where age >=16
不等于 { key : { $ne : value } db.user.find({“age”:{$ne: 16}}) where age <> 16
//查看所有文档记录
db.collection_name.find()

// 查询一个文档
db.collection_name.findOne();

// 条件查询
// 条件查询 ==
db.user.find({"name":"Gorit111"})  // where name = "张三"  全匹配

// 条件查询 小于
db.user.find({"age":{$lt:17}}); // where age < 17

// 条件查询 小于或等于
db.user.find({"age":{$lte:20}}); // where age <= 20

// 条件查询 大于
db.user.find({"age":{$gt:16}}); // where age > 10

// 条件查询 大于或等于
db.user.find({"age":{$gte:16}}); // where age >= 16

// 条件查询  不等于
db.user.find({"age":{$ne: 16}})

4.2 逻辑查询

// 逻辑与 and 查询
db.user.find({"age":17},{"id":"1"})

// 逻辑或 or 查询
db.user.find(
    {
        $or: [
            {"age":17},
            {"id":"1"}
        ]
    }
)

// 组合查询练习
where age <=20 or (name in ("张三","Gorit111")
db.user.find(
    {
        "age": {$lte: 20},
        $or: [
        {
            "name": "张三"
        },{
            "name": "Gorit111"
        }]
    }
)

4.3 分页查询
  1. 分页参数 Limit()
db.collection_name.find().limit(number);

// 查询数据库汇中的三条记录,如果数据库没有指定 limit() ,默认查询所有的数据
db.user.find().limit(3);
  1. 使用 skip() 跳跃指定数量的数据
// 跳过第一条记录,查询往后的三条记录
db.user.find().limit(3).skip(1);

4.4 排序

在 MangoDB 中使用 sort() 方法对数据进行排序, sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来制定排序方式,1 表示升序列,-1 表示降序列

// 根据年龄升序
db.user.find().sort({"age":1})

// 根据年龄降序排列
db.user.find().sort({"age":-1});

4.5 聚合

MangoDB 中聚合(aggregate)主要用于处理数据(诸如平均值,求和等)并返回计算的结果

不过我下的版本貌似不支持聚合查询,所这里就不掩饰了。

3.3 数据库连接工具连接 MangoDB

有很多工具都可以连接,我使用的是 Jetbrains 公司提供的数据库连接软件:datagrip

当然使用 idea 自带的也可以

或者用其他的工具都行的

6.2.2 MongoDB - 图2

四、Java 连接 MangoDB

作为一名 Java 开发者,我们怎么能少了 Java 连接 mangoDB 呢?

接下来进入实战部分

4.1 SpringBoot 整合 MongoDB

SpringBoot 整合 MongoDB 整合

  1. 依赖导入
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
  1. 配置文件编写

为了方便测试,我这里

# 应用服务 WEB 访问端口
server:
  port: 8080
# 应用名称
spring:
  application:
    name: demo
  resources: # spring 静态资源扫描路径
    static-locations: classpath:/static/
  data:
    mongodb:
      database: test  # 要连接的数据库
      host: localhost  # 数据库地址
      port: 27017 # 端口
      #authentication-database: admin       # 验证登录信息库
      #username: # 连接数据库的账号
      #password: # 连接书库的密码
  1. 实战

编写实体类

package cn.gorit.entity;

/**
 * @Classname Book
 * @Description TODO
 * @Date 2020/11/9 21:48
 * @Created by CodingGorit
 * @Version 1.0
 */
public class Book {
    private Integer id;
    private String name;
    private String author;

    // getter setter 构造方法省略
}

编写 BookDao

package cn.gorit.dao;

import cn.gorit.entity.Book;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

/**
 * @Classname BookDao
 * @Description TODO
 * @Date 2020/11/9 21:48
 * @Created by CodingGorit
 * @Version 1.0
 */
public interface BookDao extends MongoRepository<Book,Integer> {
    List<Book> findAllByAuthor(String author);

    Book findByNameEquals(String name);
}

编写 BookController

package cn.gorit.controller;

import cn.gorit.dao.BookDao;
import cn.gorit.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname BookController
 * @Description TODO
 * @Date 2020/11/9 21:51
 * @Created by CodingGorit
 * @Version 1.0
 */
@RestController
public class BookController {

    // 实用内齿提供的 baseMongo
    @Autowired
    BookDao dao;

    // 实用 内置的template
    @Autowired
    MongoTemplate template;

    @GetMapping("/test1")
    public void test1() {
        List<Book> books = new ArrayList<>();
        books.add(new Book(1,"年华","ls"));
        books.add(new Book(2,"楼记","ls"));
        dao.insert(books);
        List<Book> b1 = dao.findAllByAuthor("ls");
        System.out.println(b1.toString());
        System.out.println(dao.findByNameEquals("楼记"));
    }

    @GetMapping("/test2")
    public void test2() {
        List<Book> books = new ArrayList<>();
        books.add(new Book(3,"围城","钱钟书"));
        books.add(new Book(4,"宋诗选注","钱钟书"));

        template.insertAll(books);
        List<Book> list = template.findAll(Book.class);
        System.out.println(list);
        Book book = template.findById(3,Book.class);
        System.out.println(book);
    }
}

接口测试
6.2.2 MongoDB - 图3