• 非关系数据库之mongodb入门到实战(7)mongodb的window版安装与使用详解


    第一章 数据库的概述

    1.1 什么是数据库

      • 数据库是按照数据结构来组织、存储和管理数据的仓库。
      • 我们的程序都是在内存中运行的,一旦程序运行结束或者计算机断电,程序运行中的数据都会丢失。
      • 所以我们就需要将一些程序运行的数据持久化到硬盘之中,以确保数据的安全性。而数据库就是数据持久化的最佳选择。
      • 说白了,数据库就是存储数据的仓库。

    1.2 数据库分类

    数据库主要分成两种:
    关系型数据库
      • MySQL、Oracle、DB2、SQL Server ……
      关系数据库中全都是表
    非关系型数据库
      • MongoDB、Redis ……
      • 键值对数据库
      • 文档数据库 MongoDB

    第二章 MongoDB 的简介、下载、安装、启动、配置和关闭

    2.1 MongoDB 简介

    • MongoDB 是为快速开发互联网 Web 应用而设计的数据库系统。
    • MongoDB 的设计目标是极简、灵活、作为 Web 应用栈的一部分。
    • MongoDB 的数据模型是面向文档的,所谓文档是一种类似于 JSON 的结构,简单理解:MongoDB 这个数据库中存的是各种各样的 JSON。(BSON)

    2.2 下载 MongoDB

    • 下载地址:https://www.mongodb.org/dl/win32/
    • MongoDB 的版本偶数版本为稳定版,奇数版本为开发版。
    • MongoDB 对于 32 位系统支持不佳,所以 3.2 版本以后没有再对 32 位系统的支持。
    • 本博主下载的版本是:mongodb-win32-x86_64-2008plus-ssl-3.2.4-signed

    2.3 安装 MongoDB

    1、双击安装文件 mongodb-win32-x86_64-2008plus-ssl-3.2.4-signed


    2、点击接受协议

    3、选择自定义安装

    4、选择安装目录

    5、点击安装

    6、安装过程中

    7、安装完成

    8、MongoDB 的安装目录结构

    2.4 启动 MongoDB

    1、将 MongoDB 的 bin 目录添加到 path 下(这里我们使用 bruce 的用户变量


    2、在 C 盘根目录下创建 data 文件夹,在 data 下创建 db 文件夹,该文件用于存放 MongoDB 的文件,在 data 下创建 db 文件夹

    启动 mongodb 服务器,打开 cmd 命令行窗口,输入:mongod

    • 32操作系统位注意:第一次启动 mongodb 服务器时,需要输入如下内容:
      mongod --storageEngine=mmapv1
      第一次启动后,再次启动 mongodb 服务器时,只需输入 mongodb 即可。

    • 如果我们不想使用 mongodb 提供的默认数据库路径和端口,该如何做呢?
    答:在控制台启动 mongodb 时,可以指定路径和端口
      mongod --dbpath 数据库路径 --port 端口号
      示例:mongod --dbpath C:UsersruceDesktopmongodatadb --port 123

    3、再重新打开一个 cmd 窗口,输入 mongo 连接 mongodb 数据库,出现下图


    注意:打开的命令行窗口不能关闭。 

    2.5 配置 MongoDB 的 windows 服务

    将 MongoDB 设置为系统服务,可以自动在后台启动,不需要每次都手动启动。
    1、在 c 盘根目录创建 data,在 data 下创建 db 和 log 文件夹

    2、创建配置文件,在目录 D:workMongoDBServer3.2 下添加一个配置文件 mongod.cfg,并添加如下内容

    systemLog:
        destination: file
        path: c:datalogmongod.log
    storage:
        dbPath: c:datadb

    3、以管理员的身份打开命令行窗口,执行如下的命令:

    sc.exe create MongoDB binPath= ""D:workMongoDBServer3.2inmongod.exe" --service --config="D:workMongoDBServer3.2mongod.cfg"" DisplayName= "MongoDB" start= "auto"

    sc.exe create MongoDB binPath= ""mongod的bin目录mongod.exe" --service --config="mongo的安装目录mongod.cfg"" DisplayName= "MongoDB" start= "auto"

    4、打开命令行,启动 mongodb 服务

    5、如果启动失败,证明上边的操作有误,在控制台输入 sc delete MongoDB 删除之前配置的服务,然后从第一步再来一次。

    2.6 关闭 MongoDB

    1、打开新的命令行窗口,输入命令,登录到服务器

    mongo

    2、切换管理员用户

    use admin;

    3、关闭数据库

    db.shutdownServer();

    第三章 MongoDB 的基本操作

    3.1 MongoDB 的基本概念

    数据库(database):数据库是一个仓库,在仓库中可以存放集合。
    集合(collection):集合类似于数组,在集合中可以存放文档。
    文档(document):文档是数据库中最小单位,我们存储和操作的内容都是文档。

    在 MongoDB 中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合。

    文档(document):类似于 JS 中的对象,在 MongoDB 中每一条数据都是一个文档。
    集合(collection):集合就是一组文档,也就是集合是用来存放文档的。
    集合中存储的文档可以是各种各样的,没有格式要求,多个文档组成集合,多个集合组成数据库。

    3.2 基本指令


    常用指令举例:

    show dbs
    show databases
        - 显示当前的所有数据库

    use 数据库名
        - 进入到指定的数据库中

    db
        - db表示的是当前所处的数据库

    show collections
        - 显示数据库中所有的集合

    Mongo Shell 小解

    3.3 数据库的 CRUD(增删改查)的操作

    - 向数据库中插入文档
        db.<collection>.insert(doc(s));
            - 向指定的集合插入一个或多个文档,如果集合不存在则创建
            - 具体示例:db.users.insert({username:"sunwukong",age:18,gender:"male"})
        db.<collection>.find();
            - 查询当前集合中的所有文档
            - 具体示例:db.users.find()
        db.<collection>.count();
            - 统计集合中文档的数量
            - 具体示例:db.users.count()
        db.collection.remove();
            - 删除文档
        db.collection.drop();
            - 删除集合

    3.4 安装图形化工具

    1、双击 mongodbmanagerfree_inst.exe


    2、选择接受

    3、选择安装目录

    4、全部选上

    5、选择 next

    6、创建桌面快捷方式

    7、点击安装

    8、安装完成

    9、选择接受

    10、输入连接 MongoDB 数据库的 IP 地址和 端口

    11、点击 “+” 号,连接成功

    3.5 文档的增删改查

    插入文档
      db.collection.insert();
      insert() 可以用于向集合中添加一个或多个文档,可以传递一个对象,或一个数组。
      可以将对象或数组中的对象添加进集合中,添加时如果集合或数据库不存在,会自动创建。
      插入的文档对象会默认添加_id 属性,这个属性对应一个唯一的id,是该文档的唯一标识。 _id 属性可以自己指定

    db.users.insert({username: "sunwukong", age: 18, gender: "male"});   // 默认id
    db.users.insert({_id: "001", username: "sunwukong", age: 18, gender: "male"});   // 自己指定id

    db.users.insert([
        {username: "sunwukong", age: 18, gender: "male"},
        {username: "zhubajie", age: 20, gender: "male"},
        {username: "shaheshang", age:25, gender: "female"}
    ]);

    db.users.insertOne();   // 插入一个文档对象,从 3.2 版本开始有该方法
    db.users.insertMany();  // 插入多个文档对象,从 3.2 版本开始有该方法

    查询文档
      db.collection.find()
      find() 用来查询集合中的所有符合条件的文档。
      find() 中可以接收一个条件参数。

    db.users.find();  // 查询集合中的所有文档

    db.users.find({});  // 查询集合中的所有文档

    db.users.find({_id: "001"});

    db.users.find({username: "sunwukong"});

    db.users.find({username: "sunwukong", age: 25});

    db.users.find({age:25});      // 返回的是一个文档对象的数组
    db.users.find({age:25})[1];
    db.users.find({age:25})[5];
    db.users.findOne({age:25});           // 查询符合条件的第一个文档对象
    db.users.findOne({age:25}).name;      // 查询一个符合条件的文档对象的属性值
    db.users.findOne({age:25}).count();   // 查询一个符合条件的文档对象的属性值(该方法常用)
    db.users.findOne({age:25}).length();  // 查询一个符合条件的文档对象的属性值(该方法不常用)

    删除文档
      db.collection.remove()
      remove()可以用来移除指定文档对象,该方法接收一个查询文档作为参数,只有符合条件的文档才会被删除。
      删除数据是永久的,不能撤销。

    db.users.remove({_id: "001"});       // 删除一个或多个符合条件的文档对象

    db.users.remove({age: 25, true});    // 只删除一个符合条件的文档对象

    db.users.remove({});    // 删除所有的文档对象(即清空集合,性能略差),集合还在

    db.users.deleteOne();
    db.users.deleteMany();

    删除集合
      db.collection.drop()

    db.users.drop();    // 删除集合(性能好),集合不存在

    删除数据库
      db.dropDatabase()
      数据库中的数据一般不会删除,所以删除方法一般不用。
      一般会在数据中增加一个字段,来表示数据是否被删除。(即通过数据冗余)

    修改文档
      db.collection.update()
      可以在 update() 中传递两个参数,第一个是查询文档,第二个是新的文档,这样符和条件的文档将会被新文档所【替换】,即旧的对象没有了。
      update() 的第三个参数,用来指定是否使用 upsert,默认为 false。
      update() 的第四个参数,用来指定是否同时修改多个文档,默认为 false。
      如果需要修改指定的值,而不是替换,需要使用【修改操作符】来完成修改。
        $set 修改文档中的指定属性
        $unset 删除文档中指定的属性
        $inc 自增文档中指定的属性的值
        $push 
        $addToSet

    db.users.update({username: "sunwukong"}, {age: 10});           // 新的文档对象替换旧的文档对象(只替换符合条件的第一个文档对象)
    db.users.replaceOne({username: "sunwukong"}, {age: 100});      // 新的文档对象替换旧的文档对象(只替换符合条件的第一个文档对象)

    db.users.update({username: "sunwukong"}, {$set: {age: 10}});                // 替换旧的文档对象中某个属性的值(只替换符合条件的第一个文档对象)
    db.users.update({username: "sunwukong"}, {$set: {age: 10}}, {multi: true});   // 替换旧的文档对象中某个属性的值(替换符合条件的一个或多个文档对象)

    db.users.update({username: "sunwukong"}, {$unset: {age: 10}});  // 删除旧的文档对象中某个属性

    db.users.updateOne({username: "sunwukong"}, {$set: {age: 10}});     // 替换旧的文档对象中某个属性的值(只替换符合条件的第一个文档对象)
    db.users.updateMany({username: "sunwukong"}, {$set: {age: 10}});    // 替换旧的文档对象中属性的值(替换符合条件的一个或多个文档对象)

    3.6 练习题

    // 1.进入 my_test 数据库
    use my_test;

    // 2.向数据库的 user 集合中插入一个文档  
    db.users.insert({
        username: "sunwukong"
    });

    // 3.查询 user 集合中的文档
    db.users.find();

    // 4.向数据库的 user 集合中插入一个文档   
    db.users.insert({
        username: "zhubajie"
    });

    // 5.查询数据库 user 集合中的文档
    db.users.find();

    // 6.统计数据库user集合中的文档数量
    db.users.find().count();

    // 7.查询数据库 user 集合中 username 为 sunwukong 的文档
    db.users.find({username: "sunwukong"});

    // 8.向数据库 user 集合中的 username 为 sunwukong 的文档,添加一个 address 属性,属性值为 huaguoshan
    db.users.update({username: "sunwukong"}, {$set: {address: "huaguoshan"}});


    // 9.使用{username: "tangseng"} 替换 username 为 zhubajie的 文档
    db.users.replaceOne({username: "zhubajie"}, {username: "tangseng"});    

    // 10.删除 username 为 sunwukong 的文档的 address 属性
    db.users.update({username: "sunwukong"}, {$unset: {address: 1}});

    // 11.向 username 为 sunwukong 的文档中,添加一个 hobby: {cities: ["beijing", "shanghai", "shenzhen"], movies: ["sanguo", "hero"]}
    // MongoDB 的文档的属性值也可以是一个文档,当一个文档的属性值是一个文档时,我们称这个文档叫做内嵌文档。
    db.users.update({username: "sunwukong"}, {$set: {hobby: {cities: ["beijing", "shanghai", "shenzhen"], movies: ["sanguo", "hero"]}}});
    db.users.find();

    // 12.向 username 为 tangseng 的文档中,添加一个 hobby: {movies: ["A Chinese Odyssey", "King of comedy"]}
    db.users.update({username: "tangseng"}, {$set: {hobby: {movies: ["A Chinese Odyssey", "King of comedy"]}}})

    // 13.查询喜欢电影 hero 的文档
    // MongoDB 支持直接通过内嵌文档的属性进行查询,如果要查询内嵌文档则可以通过.的形式来匹配
    // 如果要通过内嵌文档来对文档进行查询,此时属性名必须使用引号(单双引号均可)
    db.users.find({"hobby.movies": "hero"});
    db.users.find({'hobby.movies': "hero"});

    // 14.向 tangseng 中添加一个新的电影 Interstellar
    // $push 用于向数组中添加一个新的元素(即可以重复添加)
    // $addToSet 向数组中添加一个新元素,如果数组中已经存在了该元素,则不会添加(即不可以重复添加)
    db.users.update({username: "tangseng"}, {$push: {"hobby.movies": "Interstellar"}});
    db.users.update({username: "tangseng"}, {$addToSet: {"hobby.movies": "Interstellar"}});
    db.users.find();

    // 15.删除喜欢 beijing 的用户
    db.users.remove({"hobby.cities": "beijing"});

    // 16.删除 user 集合
    db.users.remove({});    // 删除所有的文档对象(即清空集合,性能略差),集合还在
    db.users.drop();

    show dbs;

    // 17.向 numbers 中插入 20000 条数据 7.2s
    // 方式一:太慢
    for(var i=1 ; i<=20000 ; i++){
        db.numbers.insert({num:i});
    }

    db.numbers.find()
    db.numbers.remove({});

    // 方式二:先 push 进数组,再 insert 进集合,0.4s
    var arr = [];
    for(var i = 1; i <= 20000; i++){
        arr.push({num: i});
    }
    db.numbers.insert(arr);

    // 18.查询 numbers 中 num 为 500 的文档
    db.numbers.find({num: 500})
    db.numbers.find({num: {$eq: 500}});

    // 19.查询numbers中num大于5000的文档
    db.numbers.find({num: {$gt: 500}});

    // 20.查询numbers中num小于30的文档
    db.numbers.find({num: {$lt: 30}});

    // 21.查询 numbers 中 num 大于 40 小于 50 的文档
    db.numbers.find({num: {$gt: 40, $lt: 50}});

    // 22.查询 numbers 中 num 大于 19996 的文档
    db.numbers.find({num: {$gt: 19996}});

    // 23.查看 numbers 集合中的前 10 条数据
    db.numbers.find({num: {$lte: 10}});

    // limit() 设置显示数据的上限
    db.numbers.find().limit(10);
    // 在开发时,我们绝对不会执行不带条件的查询
    db.numbers.find();

    //24.查看 numbers 集合中的第 11 条到 20 条数据
    /*
        分页 每页显示10条
            1-10     0
            11-20    10
            21-30    20
            。。。

        skip((页码-1) * 每页显示的条数).limit(每页显示的条数);

        skip() 用于跳过指定数量的数据。    

        MongoDB 会自动调整 skip 和 limit 的位置。
    */
    db.numbers.find().skip(10).limit(10);

    // 25.查看 numbers 集合中的第 21 条到 30 条数据
    db.numbers.find().skip(20).limit(10);
    db.numbers.find().limit(10).skip(10);

    // 26.将 dept 和 emp 集合导入到数据库中
    db.dept.find();
    db.emp.find();

    db.dept.drop();
    db.emp.drop();

    // 27.查询工资小于 2000 的员工
    db.emp.find({sal: {$lt: 2000}});

    // 28.查询工资在 1000-2000 之间的员工
    db.emp.find({sal: {$gt: 1000, $lt: 2000}});

    // 29.查询工资小于 1000 或大于 2500 的员工
    db.emp.find({$or: [{sal: {$lt: 1000}}, {sal: {$gt: 2500}}]});

    // 30.查询财务部的所有员工
    //(deptno)
    var deptno = db.dept.findOne({dname: "财务部"}).deptno;
    db.emp.find({deptno: deptno});

    // 31.查询销售部的所有员工
    var deptno = db.dept.findOne({dname: "销售部"}).deptno;
    db.emp.find({deptno: deptno});

    // 32.查询所有 mgr 为 7698 的所有员工
    db.emp.find({mgr: 7698});

    // 33.为所有薪资低于 1000 的员工增加工资 400 元
    db.emp.updateMany({sal: {$lte: 1000}}, {$inc: {sal: 400}});
    db.emp.find();

    3.7 文档中的关系

    文档之间的关系:
    一对一:在 MongoDB 中可以通过内嵌文档的形式来体现出一对一的关系。

    db.wifeAndHusband.insert([
        {
            name: "黄蓉",
            husband: {
                name: "郭靖"
            }
        }, {
            name: "潘金莲",
            husband: {
                name:"武大郎"
            }
        }
    ]);

    一对多:也可以通过内嵌文档来映射一对多的关系。在多的表中存放一的id。

    db.users.insert([
        {
            username: "swk"
        }, {
            username:"zbj"
        }
    ]);
    db.order.insert({
        list: ["牛肉","漫画"],
        user_id: ObjectId("59c47e35241d8d36a1d50de0")
    });

    多对多:

    db.teachers.insert([
        {name:"洪七公"},
        {name:"黄药师"},
        {name:"龟仙人"}
    ]);

    db.stus.insert([
        {
            name:"郭靖",
            tech_ids: [
                ObjectId("59c4806d241d8d36a1d50de4"),
                ObjectId("59c4806d241d8d36a1d50de5")
            ]
        }, {
            name:"孙悟空",
            tech_ids: [
                ObjectId("59c4806d241d8d36a1d50de4"),
                ObjectId("59c4806d241d8d36a1d50de5"),
                ObjectId("59c4806d241d8d36a1d50de6")
            ]
        }
    ])

    3.8 sort 和投影

    //查询文档时,默认情况是按照_id的值进行排列(升序)
    //sort() 可以用来指定文档的排序的规则,sort() 需要传递一个对象来指定排序规则,1 表示升序显示该字段的数据;-1 表示降序显示该字段的数据,0 表示不显示该字段的数据。
    //limit、skip、sort 可以以任意的顺序进行调用
    db.emp.find({}).sort({sal: 1, empno: -1}); // 按照工资升序排序,工资相同时按照员工编号降序排序

    //在查询时,可以在第二个参数的位置来设置查询结果的--即投影
    db.emp.find({}, {ename: 1, _id: 0, sal: 1}); 

    第四章 Mongoose

    4.1 Mongoose 的简介

      之前我们都是通过 shell 来完成对数据库的各种操作的,在开发中大部分时候我们都需要通过程序来完成对数据库的操作。
      而 Mongoose 就是一个让我们可以通过 Node 来操作 MongoDB 的模块。
      Mongoose 是一个对象文档模型(ODM)库,它对 Node 原生的 MongoDB 模块进行了进一步的优化封装,并提供了更多的功能。
      在大多数情况下,它被用来把结构化的模式应用到一个 MongoDB 集合,并提供了验证和类型转换等好处。

    4.2 Mongoose 的好处

    • 可以为文档创建一个模式结构(Schema)
    • 可以对模型中的对象/文档进行验证
    • 数据可以通过类型转换转换为对象模型
    • 可以使用中间件来应用业务逻辑挂钩
    • 比 Node 原生的 MongoDB 驱动更容易

    4.3 新的对象

    mongoose 中为我们提供了几个新的对象:
    Schema(模式对象)
      • Schema 对象定义约束了数据库中的文档结构。
    Model
      • Model 对象作为集合中的所有文档的表示,相当于 MongoDB 数据库中的集合 Collection。
    Document
      • Document 表示集合中的具体文档,相当于集合中的一个具体的文档。

    4.4 通过 Mongoose 连接 MongoDB

    1、使用 Mongoose 必须先安装 mongoose 包
      npm i mongoose --save 或者
      npm install mongoose
    2、加载 Mongoose
      const mongoose = require("mongoose");
    3、连接 MongoDB 数据库
      mongoose.connect("mongodb://地址", {useMongoClient: true});
      地址例子:mongodb://127.0.0.1:27017/mg_test
      如果端口号是默认端口号,则可以省略不写。
      注意:不同的 MongoDB 版本, connect() 函数中的参数不一样。
    4、监听数据库的连接状态(一般不需要调用)
      在 Mongoose 对象中有一个属性叫做 connection,该对象表示的就是数据库连接,通过监视该对象的状态。可以监听数据库的连接与断开。
      mongoose.connection.once("open", function() {}); // 数据库连接成功的事件
      mongoose.connection.once("close", function() {}); // 数据库连接断开的事件
    5、断开连接(一般不需要调用)
      mongoose.disconnect();
      对于 MongoDB 数据库。一般情况下。只需要连接一次,连接一次成功后,除非项目停止服务器关闭,否则连接一般不会断开。因为 MongoDB 数据库没有事务控制。

    Connection
      一旦连接了 MongoDB 数据库,底层的 Connection 对象就可以通过 mongoose 模块的connection属性来访问。
      connection 对象是对数据库连接的抽象,它提供了对象连接、底层的 DB 对象和表示结合的 Model 对象的访问。
      并且可以对 connection 对象上的一些事件进行监听,来获悉数据库连接的开始与端开。比如,可以通过 open 和 close 事件来监控连接的打开和关闭。

    4.5 Schema--模式对象(约束对象)

      使用 Mongoose 你必须经常定义模式。
      模式为集合中的文档定义字段和字段类型。
      如果你的数据是被结构化成支持模式的,这是非常有用的。
      简单来说,模式就是对文档的约束,有了模式,文档中的字段必须符合模式的规定。否则将不能正常操作。

    4.6 Model--模型对象

      一旦定义好了 Schema 对象,就需要通过该 Schema 对象来创建 Model 对象。
      一旦创建好了 Model 对象,就会自动和数据库中对应的集合建立连接,以确保在应用更改时,集合已经创建并具有适当的索引,且设置了必须性和唯一性。
      Model 对象就相当于数据库中的集合,通过 Model 可以完成对集合的 CRUD 操作。

    示例js代码如下:

    var mongoose = require('mongoose');
    mongoose.connect("mongodb://127.0.0.1/mongoose_test", {useMongoClient: true});
    mongoose.connection.once("open", function() {
        console.log("数据库连接成功~~~");
    });

    var Schema = mongoose.Schema;  // 注意:Schema 该变量名使用大写,表示构造函数。

    // 创建 Schema(模式)对象
    var stuSchema = new Schema({  // 注意:stuSchema 该变量名使用小写,习惯写法。
        name: String,
        ageNumber,
        gender: {
            typeString,
            default"female"
        },
        addressString
    });

    // 通过 Schema 来创建 Model,Model 代表的是数据库中的集合,通过 Model 才能对数据库进行操作
    // mongoose.model(modelName, schema): // modelName 就是要映射的集合名称,mongoose 会自动将集合名称变成复数。
    var StuModel = mongoose.model("student", stuSchema); // 注意:StuModel 该变量名使用大写,表示构造函数。
    // StuModel.create(doc, function(err){}); // 向数据库中插入一个文档
    StuModel.create({
        name"白骨精",
        age16,
        address"白骨洞"
    }, function (err{
        if (!err) {
            console.log("插入成功~~~");
        }
    });

    4.7 Model 对象的方法

    • remove(conditions, callback)
    • deleteOne(conditions, callback)
    • deleteMany(conditions, callback)
    • find(conditions, projection, options, callback)
    • findById(id, projection, options, callback)
    • findOne(conditions, projection, options, callback)
    • count(conditions, callback)
    • create(doc, callback)
    • update(conditions, doc, options, callback)
    等等

    示例js代码如下:

    var mongoose = require('mongoose');
    mongoose.connect("mongodb://127.0.0.1/mongoose_test", {useMongoClient: true});
    mongoose.connection.once("open", function() {
        console.log("数据库连接成功~~~");
    });

    var Schema = mongoose.Schema;  // 注意:Schema 该变量名使用大写,表示构造函数。

    // 创建 Schema(模式)对象
    var stuSchema = new Schema({  // 注意:stuSchema 该变量名使用小写,习惯写法。
        name: String,
        ageNumber,
        gender: {
            typeString,
            default"female"
        },
        addressString
    });

    -----------------------------------------------------

    // 通过 Schema 来创建 Model,Model 代表的是数据库中的集合,通过 Model 才能对数据库进行操作
    // mongoose.model(modelName, schema): // modelName 就是要映射的集合名称,mongoose 会自动将集合名称变成复数。
    var StuModel = mongoose.model("student", stuSchema); // 注意:StuModel 该变量名使用大写,表示构造函数。
    // StuModel.create(doc, function(err){}); // 向数据库中插入一个文档
    StuModel.create({
        name"白骨精",
        age16,
        address"白骨洞"
    }, function (err{
        if (!err) {
            console.log("插入成功~~~");
        }
    });

    -----------------------------------------------------

    var StuModel = mongoose.model("student" , stuSchema);

    StuModel.create([
        {
            name"沙和尚",
            age38,
            gender"male",
            address"流沙河"
        }
    ], function (err{
        if (!err) {
            console.log(arguments); // arguments 该参数是返回的插入的文档,一般用的比较少。
        }
    });

    -----------------------------------------------------

    /*
        - 有了 Model,我们就可以来对数据库进行增删改查的操作了!

         Model.create(doc(s), [callback])
         - 用来创建一个或多个文档并添加到数据库中
         - 参数:
             doc(s) 可以是一个文档对象,也可以是一个文档对象的数组。
             callback 当操作完成以后调用的回调函数。

    查询的方法:
        Model.find(conditions, [projection], [options], [callback])
            - 查询所有符合条件的文档,总会返回一个数组
        Model.findById(id, [projection], [options], [callback])
            - 根据文档的id属性查询文档
        Model.findOne([conditions], [projection], [options], [callback])
            - 查询符合条件的第一个文档,总会返回一个具体的文档对象

        参数解释:
             conditions  查询的条件
             projection  投影,需要获取到的字段
                 - 两种方式:
                     方式一:{name: 1, _id: 0}   // 只显示name,不显示id
                     方式二:"name -_id"         // 只显示name,不显示id
             options     查询选项(常用 skip、limit)
                     示例:{skip: 3, limit: 1}
             callback    回调函数,查询结果会通过回调函数返回
                         这里回调函数必须传,如果不传回调函数,压根就不会去查询
    */

    -----------------------------------------------------
    StuModel.find({name"唐僧"}, function(err, docs{
        if (!err) {
            console.log(docs);
        }
    });

    StuModel.find({}, {name1_id0}, function(err, docs{
        if (!err) {
            console.log(docs);
        }
    });

    StuModel.find({}, "name age -_id", {skip3limit1}, function(err, docs{
        if (!err) {
            console.log(docs);
        }
    });

    StuModel.findOne({}, function(err, doc{
        if (!err) {
            console.log(doc);
        }
    });

    StuModel.findById("59c4c3cf4e5483191467d392"function(err, doc{
        if (!err) {
            // console.log(doc);
            // 通过 find() 查询的结果,返回的对象就是 Document 对象或 Document 对象数组。
            // Document 对象是 Model 的实例
            console.log(doc instanceof StuModel); // 验证 Document 对象是否是 Model 的实例,使用 【文档对象 instanceof 模型对象】
        }
    });

    -----------------------------------------------------

    /* 修改
        Model.update(conditions, doc, [options], [callback])
        Model.updateMany(conditions, doc, [options], [callback])
        Model.updateOne(conditions, doc, [options], [callback])
        Model.replaceOne(conditions, doc, [options], [callback])
        - 用来修改一个或多个文档
        - 参数:
             conditions 查询条件
             doc 修改后的对象
             options 配置参数
             callback 回调函数    
    */
    // 修改唐僧的年龄为 20
    StuModel.updateOne({name"唐僧"}, {$set: {age20}}, function(err{
        if (!err){
            console.log("修改成功~~~");
        }
    });

    -----------------------------------------------------

    /* 删除:
        Model.remove(conditions, [callback])
        Model.deleteOne(conditions, [callback])
        Model.deleteMany(conditions, [callback])
    */
    StuModel.remove({name"白骨精"}, function(err{
        if (!err) {
            console.log("删除成功~~~");
        }
    });

    -----------------------------------------------------

    /*
        Model.count(conditions, [callback])
         - 统计文档的数量
    */
    StuModel.count({}, function(err, count{
        if (!err) {
            console.log(count);
        }
    });

    4.8 Document--文档对象

      通过 Model 对数据库进行查询时,会返回 Document 对象或 Document 对象数组。
      Document 继承自 Model,代表一个集合中的文档。
      Document 对象也可以和数据库进行交互操作。

    4.9 Document 对象的方法

    • equals(doc)
    • id
    • get(path, [type])
    • set(path, value, [type])
    • update(update, [options], [callback])
    • save([callback])
    • remove([callback])
    • isNew
    • isInit(path)
    • toJSON()
    • toObject()

    示例js代码如下:

    var mongoose = require("mongoose");
    mongoose.connect("mongodb://127.0.0.1/mongoose_test", {useMongoClient: true});
    mongoose.connection.once("open", function() {
        console.log("数据库连接成功~~~");
    });

    var Schema = mongoose.Schema;
    var stuSchema = new Schema({
        name: String,
        age: Number,
        gender: {
            type: String,
            default: "female"
        },
        address: String
    });

    var StuModel = mongoose.model("student", stuSchema);

    -----------------------------------------------------

    /*
        Document 和 集合中的文档一一对应, Document 是 Model 的实例。
        通过 Model 查询到结果都是 Document 对象或 Document 对象数组。
     */

    // 自己创建一个 Document
    var stu = new StuModel({
        name"奔波霸",
        age48,
        gender"male",
        address"碧波潭"
    });

    // Document 的方法:Model#save([options], [fn])
    stu.save(function (err{
        if (!err) {
            console.log("保存成功~~~");
        }
    });

    StuModel.findOne({}, function(err, doc{
        if (!err) {
            // console.log(doc);

            /*
                修改对象:update(update, [options], [callback])
                删除对象:remove([callback])
             */
            // 修改方式一:
            doc.update({$set: {age28}}, function(err{
                if (!err) {
                    console.log("修改成功~~~");
                }
            });

            // 修改方式二:
            // doc.age = 18;
            // doc.save();

            doc.remove(function (err{
                if (!err) {
                    console.log("大师兄再见~~~");
                }
            });

            /*
                get(name)
                    - 获取文档中的指定属性值
                set(name, value)
                    - 设置文档的指定的属性值
                id
                    - 获取文档的 _id 属性值
                 toJSON()
                    - 转换为一个 JSON 对象
                 toObject() 该 Document 对象的方法很常用!!!
                    - 将 Document 对象转换为一个普通的 js 对象。转换为普通的 js 对象以后,所有的 Document 对象的方法或属性都不能使用了。
             */
            // console.log(doc.get("age"));
            // console.log(doc.age);

            // doc.set("name", "猪小小");
            // doc.name = "hahaha";

            // console.log(doc._id);
            // var j = doc.toJSON();
            // console.log(j);

            // var o = doc.toObject();
            // console.log(o);

            // 转为 js 对象后,再删除 js 对象的属性(用于保护隐私数据)
            js = doc.toObject();
            delete js.address;
            // console.log(js.id); // 错误
            console.log(js._id); // id 是 Document 对象的属性,而 _id 是 js 对象的属性
        }
    });

    4.10 Mongoose 的模块化

    1、定义一个模块,用于连接 MongoDB 数据库
    conn_mongo.js

    var mongoose = require("mongoose");
    mongoose.connect("mongodb://127.0.0.1/mongoose_test", {useMongoClient: true});
    mongoose.connection.once("open", function() {
        console.log("数据库连接成功~~~");
    });

    在新的 js 文件中如何使用上述模块呢?如下:

    require("./utils/conn_mongo");

    2、定义一个模块,用于定义具体的模型对象
    第一种方式:
    student.js

    var mongoose = require("mongoose");
    var Schema = mongoose.Schema;
    var stuSchema = new Schema({
        name: String,
        age: Number,
        gender: {
            type: String,
            default: "female"
        },
        address: String
    });
    var StuModel = mongoose.model("student", stuSchema);

    // 将具体的模型对象暴露出去
    exports.model = StuModel;

    在新的 js 文件中如何使用上述模块呢?间接引用,如下:

    var Student = require("./utils/student").model;

    第二种方式:
    student.js

    var mongoose = require("mongoose");
    var Schema = mongoose.Schema;
    var stuSchema = new Schema({
        name: String,
        age: Number,
        gender: {
            type: String,
            default: "female"
        },
        address: String
    });
    var StuModel = mongoose.model("student", stuSchema);

    // 将具体的模型对象直接赋值给 exports
    module.exports = StuModel;

    在新的 js 文件中如何使用上述模块呢?直接引用,如下:

    var Student = require("./utils/student");

    第五章 使用 java 对 MongoDB 增删改查

    5.1 在 java 中解析 json

    package com.atguigu.mongo;

    import com.google.gson.Gson;
    import org.junit.Test;

    public class MyTest {

        @Test
        public void testJSON() {
            // 创建一个 JSON 字符串
            String json = "{"name":"孙悟空","age":18,"gender":"男"}";

            // 在 Java 默认情况下是不支持 JSON 的解析的
            // 需要引入第三方的 jar 包来对其进行支持
            // 1、json-lib
            // 2、jackson
            // 3、gson

            // 创建一个 Gson 解析器的实例
            Gson gson = new Gson();

            // 通过 gson 来对 json 进行解析
            // 将 json 转换为 Map 对象
            // Map map = gson.fromJson(json, Map.class);
            // System.out.println(map); // {name=孙悟空, age=18.0, gender=男}

            // 将 json 转换为 Student 对象
            Student stu = gson.fromJson(json, Student.class);
            System.out.println(stu); // Student{name='孙悟空', age=18, gender='男'}
        }

        @Test
        public void testObj() {
            // 创建一个 stu 对象
            Student stu = new Student("猪八戒"28"男");

            // 创建 Gson 解析器
            Gson gson = new Gson();
            // 将 Student 对象转换为 Gson 对象
            String json = gson.toJson(stu);

            System.out.println(json); // {"name":"猪八戒","age":28,"gender":"男"}
        }
    }

    5.2 java 版 Mongo HelloWorld

    package com.atguigu.mongo;

    import com.mongodb.MongoClient;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import org.bson.Document;
    import org.junit.Test;

    public class MongoTest {
        @Test
        public void test01() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient(); // 连接到指定的 MongoDB 数据库,如果不设置 host 和 port,则自动连接 localhost:27017
            // MongoClient mongoClient = new MongoClient("localhost", 27017);

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> usersCollection = my_testDB.getCollection("users");

            // 向 users 集合中插入文档
            // 先创建一个文档
            Document document = new Document("name""猪八戒");

            // 向文档中添加其他属性
            document.append("age"18);
            document.append("gender""男");
            document.append("address""云栈洞");

            // 插入集合
            usersCollection.insertOne(document);
        }
    }

    5.3 使用 java 对 MongoDB 增删改查

    package com.atguigu.mongo;

    import com.google.gson.Gson;
    import com.mongodb.MongoClient;
    import com.mongodb.client.FindIterable;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import org.bson.Document;
    import org.junit.Test;

    public class MongoTest {
        @Test
        public void test01() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient(); // 连接到指定的 MongoDB 数据库,如果不设置 host 和 port,则自动连接 localhost:27017
            // MongoClient mongoClient = new MongoClient("localhost", 27017);

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> usersCollection = my_testDB.getCollection("users");

            // 向 users 集合中插入文档
            // 先创建一个文档
            Document document = new Document("name""猪八戒");

            // 向文档中添加其他属性
            document.append("age"18);
            document.append("gender""男");
            document.append("address""云栈洞");

            // 插入集合
            usersCollection.insertOne(document);
        }

        /**
         * 将 自定义的对象插入 MongoDB 数据库中的集合中:自定义对象 --> JSON --> Document 对象
         */
        @Test
        public void testInsert() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient();

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> studentsCollection = my_testDB.getCollection("students");

            // 创建一个 Student 对象
            Student stu = new Student("沙和尚"38"男");

            // 将 Student 对象转换为 JSON
            Gson gson = new Gson();
            String stuJson = gson.toJson(stu);

            // 将 JSON 转换为 Document 对象
            Document document = Document.parse(stuJson);

            // 将 Document 对象插入集合中
            studentsCollection.insertOne(document);
        }

        @Test
        public void testFindOne() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient();

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> studentsCollection = my_testDB.getCollection("students");

            // 查询数据库中的文档(查询第一个文档)
            // Document document = studentsCollection.find().first();
            // System.out.println(document); // Document{{_id=5cd4cf4f97cace16f4581eb4, name=猪八戒, age=28, gender=男}}

            // 查询数据库中的文档(查询第一个文档)
            Document document = studentsCollection.find().first();
            Gson gson = new Gson();
            // 将 Document 对象转换为 JSON,然后再将 JSON 转换为 Java 对象
            Student student = gson.fromJson(document.toJson(), Student.class);
            System.out.println(student); // Student{name='猪八戒', age=28, gender='男'}
        }

        @Test
        public void testFindMany() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient();

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> studentsCollection = my_testDB.getCollection("students");

            // 查询数据库中的文档(查询多个文档)
            // FindIterable<Document> documents = studentsCollection.find().skip(2).limit(1);
            // FindIterable<Document> documents = studentsCollection.find();
            // 在 Java 中查询操作符是通过 Filters 方法来实现的
            FindIterable<Document> documents = studentsCollection.find(Filters.eq("name""沙和尚"));

            for (Document document : documents) {
                System.out.println(document.toJson());
            }
        }

        @Test
        public void testRemove() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient();

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> studentsCollection = my_testDB.getCollection("students");

            // 删除一个文档对象
            studentsCollection.deleteOne(Filters.eq("name""沙和尚"));
        }

        @Test
        public void testUpdate() {
            // 连接 MongoDB 数据库管理端
            MongoClient mongoClient = new MongoClient();

            // 连接到指定数据库
            MongoDatabase my_testDB = mongoClient.getDatabase("my_test");

            // 获取到指定的集合对象
            MongoCollection<Document> studentsCollection = my_testDB.getCollection("students");

            // 修改一个文档对象中的属性
            // db.collection.update({name: "name"}, {$set: {age: 28}});
            studentsCollection.updateOne(Filters.eq("name""沙和尚"), new Document("$set"new Document("age"28)));
        }
    }
  • 相关阅读:
    【译】使用自定义ViewHelper来简化Asp.net MVC view的开发part5(完)
    【译】使用自定义ViewHelper来简化Asp.net MVC view的开发part1
    【译】使用自定义ViewHelper来简化Asp.net MVC view的开发part3
    开发者分享在PC上制作iOS游戏的经验(上)
    dpi和ppi是什么意思
    Go语言
    逆向思维魔兽世界封包分析(2)
    关于手机游戏的部分情况调查
    《Android Dev Guide》系列教程1:什么是Android?
    拼包函数及网络封包的异常处理(含代码)
  • 原文地址:https://www.cnblogs.com/huanghanyu/p/13808850.html
Copyright © 2020-2023  润新知