Node.js集成MongoDB之MongoClient与模块化

本文将介绍MongoClient,Mongodb官方提供的Nodejs驱动,虽然已经不是Node.js操作 MongoDB的首选库了,但还是很值得学习的。目前Node.js操作 MongoDB的首选库是Mongoose,👉Node.js集成MongoDB之Mongoose入门

MongoClient

MongoClient是Mongodb官方提供的Node.js驱动,继承于mongo类(现在mongo模块被淘汰了),对MongoDB的操作和在mongo shell中几乎一致,有兴趣可以看下我这篇入门MongoDb教程

1️⃣ 基础

初始化项目

mkdir mongo-client //新建一个文件夹
cd mongo-client //进入这个文件夹

npm init -y //生成package.json
npm i mongodb //安装mongodb模块 

至此,项目目录结构应如此:

mongo-client
	├── node_modules/
	├── package-lock.json
	└── package.json

连接数据库

//simple_connect.js
const MongoClient = require("mongodb").MongoClient;
const url="mongodb://localhost/test";

MongoClient.connect(url,(err,db)=>{
    if (err) throw err;
    console.log('connected!');
    db.close();//虽说不是非要主动断开数据库连接资源,但这不失为一个好习惯
})

运行node simple_connect.js,控制台打印了connected!,预示着已经连接上了本地test数据库!但是也产生一串告警,虽然目前不影响使用,但是有代码洁癖要求的人一般无法容忍,简单看下,大约是xx要被版本抛弃,传递xxx参数以便使用新特性(这种写法其实是为了向下兼容,慢慢过渡到新版本)。之后很多运行都会产生类似告警,其实普通学习者简单了解足矣,不用太深入考虑为什么要加这个option项,就因为运行它这么提示要加上去的即可。
在这里插入图片描述
ok!改一下,就没有产生那一堆告警了。

MongoClient.connect(url,{ useUnifiedTopology: true },(err,db)=>{
    if (err) throw err;
    console.log('connected!');
    db.close();//虽说不是非要主动断开数据库连接资源,但这不失为一个好习惯
})

CRUD

主要简单介绍集合和文档的增删改查,更多(如:分页等)请查看我这篇入门MongoDb教程或者👉Node.js 连接 MongoDB,其实和Mongo Shell操作几乎一致,只是加了回调函数作为I/O反馈。以下I/O操作都是同步执行的,如果其中包含多个I/O操作,要保证其能够顺序执行,往往就会引发地狱回调。

集合

1.新建集合

//新建
MongoClient.connect(url, { useUnifiedTopology: true }, (err, db) => {
  if (err) throw err;
  const dbo = db.db("test"); //切换数据库
  dbo.createCollection("student", (err, res) => {//创建集合
    if (err) throw err;
    console.log("built");
    db.close();
  });
});

2.删除集合

//删除
  dbo.collection("student").drop((err, res) => {
    if (err) throw err;
    console.log("removed!");
    db.close();
  });

文档

1.插入文档

const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost";

MongoClient.connect(url, { useUnifiedTopology: true }, (err, db) => {
  const dbo = db.db("test");
  let doc = {
    name: "Joe",
    age: 18,
    favor: { animals: "cat", city: "guangzhou" },
  };
  const stuCol = dbo.collection("student"); //选取集合

  stuCol.insertOne(doc, (err, res) => {//插入文档
    console.log(res.result); //{ n: 1, ok: 1 }
    db.close();
  });
});

2.查询文档

let query = { age: { $gte: 18 } }; //查询条件
stuCol.find(query).toArray((err, res) => {//将查询结果转化为数组
  console.log(res);
  db.close();
});

3.修改文档

stuCol.updateOne({name:"Joe"},{$set:{"favor.city":"ShenZhen"}},(err,res)=>{//修改
  console.log(res.result);//{ n: 1, nModified: 1, ok: 1 }
  db.close();
})

4.删除文档

stuCol.deleteOne({name:'Joe'},(err,res)=>{
  console.log(res.result);//{ n: 1, ok: 1 }
  db.close();
})

异步风格(Promise Async)

对数据库的I/O操作都是异步执行的,上文的方法要保证同时对数据库的多个操作能顺序执行,那只能不停的嵌套回调函数。比如:

回调函数

//伪代码 保证先执行完文档插入操作再进行读取
 const stuCol = dbo.collection("student"); //选取集合
 
stuCol.insertOne(docObj, (err, res) => {
  stuCol.find(query).toArray((err, res) => {
    console.log(res);
    db.close();
  });
});

ES6推出了Promiseasync函数来更好进行异步编程,如果不熟悉这两个新特性的小伙伴,可以点击链接过去看看我的拙文。

Promise

1.创建集合

const MongoClient = require("mongodb").MongoClient;
const url="mongodb://localhost";

MongoClient.connect(url,{ useUnifiedTopology: true }).then((conn)=>{
    const dbo=conn.db('test');
     dbo.createCollection('teacher').then(res=>{
        console.log('collection built!');
    }).catch((e)=>{
        console.log(e);
    }).finally(()=>{
        conn.close();
    })
})

2.文档CRUD
collection.find() 返回的是Curcor对象,需要调用其toArray()方法将集合中的文档装载成数组。

MongoClient.connect(url, { useUnifiedTopology: true }).then((conn) => {
  const tchCol = conn.db("test").collection("teacher");


  let tchs = [
    { name: "GG", age: 30, subject: "Math" },
    { name: "MM", age: 26, subject: "English" },
  ];
  tchCol
    .insertMany(tchs).then(() => {  //插入数据
      return tchCol.find().toArray().then((arr) => {//尾调用 将返回值传递给下一个then方法
          console.log(arr);
        });
    }).then((res) => { //此时res是一个数组 想要继续数据库操作 那就还是使用collection对象
     return tchCol.updateOne({ name: "GG" }, { $set: { age: 28 } });//修改数据
    }).then(()=>{
        return tchCol.find().toArray().then((res) => {
            console.log(res);
          });
    })
    .catch((e) => console.log(e))
    .finally(() => {
     conn.close();
    });
}).catch(e=>console.log(e));

必须清晰每一步的操作和产生的结果!虽然没了地狱回调,讲道理,也就那样吧!
在这里插入图片描述
Async
大佬总是最后出场的!异步函数是目前书写异步编程中最优雅的,也是最适合在多次使用异步操作的时候使用。

const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost";

const ADD = 1;
const UPDATE = 2;
const QUERY = 3;
const DELETE = 4;

async function dbOperateOnTeacher(operator = 0) {
    let conn=null;
    let docs=null;
    try {
         conn = await MongoClient.connect(url, { useUnifiedTopology: true });
        const tchCol = await conn.db("test").collection("teacher");
        switch (operator) {
          case ADD:
            await tchCol.insertOne({ name: "KK", age: 42, subject: "Chinese" });
            docs=await tchCol.find().toArray();
            console.log(docs);
            break;
          case UPDATE:
            await tchCol.updateOne({ name: "KK" }, { $set: { age: 36 } });
            docs=await tchCol.find().toArray();
            console.log(docs);
            break;
          case QUERY:
            docs=await tchCol.find().toArray();
            console.log(docs);
            break;
          case DELETE:
            await tchCol.deleteOne({ name: "KK" });
            docs=await tchCol.find().toArray();
            console.log(docs);
            break;
          default:
            console.log("不知道你想干嘛");
            break;
        }
    } catch (error) {
        console.log(error);
    } finally{
        conn.close();
    }
}

(async function autoCRUD(){
    console.log("ADD");
    await dbOperateOnTeacher(ADD);
    console.log("UPDATE");
    await dbOperateOnTeacher(UPDATE);
    console.log("DELETE");
    await dbOperateOnTeacher(DELETE);
})()

在这里插入图片描述

2️⃣进阶案例 模块化

现在都是模块化编程,以下举个简单例子,操作用户的增删改查。

数据库连接类

//db_utils.js
const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost";

module.exports = {
  conn: null,
  connect(){
    return new Promise((resolve,reject)=>{
        MongoClient.connect(url, { useUnifiedTopology: true },(err,client)=>{
            if(err) reject(err);
            this.conn=client;
            resolve(this.conn);
        })
    })
  },
  close() {
    this.conn?.close();
  },
};

集合操作类
使用静态方法可以不用新建实例对象,直接通过类就可以调用方法,绑定在类对象身上,在声明类对象的时候分配内存。为了代码呈现整洁,暂未做异常捕获,使用时把每个异步函数方法体try…catch包起来即可。

//user_modal.js
const dbHelper = require("./db_utils");

class User {
  constructor(username, pwd) {
    this.username = username;
    this.pwd = pwd;
  }

  static async insertOne({ username, pwd }) {
    const conn = await dbHelper.connect();
    const dbo = conn.db("test");
    const userCol = dbo.collection("user");
    await userCol.insertOne({ username: username, pwd: pwd });
    const users = await userCol.find().toArray();
    console.log(users);
    dbHelper.close();
  }

  static async find(username) {
    const conn = await dbHelper.connect();
    const dbo = conn.db("test");
    const userCol = dbo.collection("user");
    const user = await userCol.find({ username: username }).toArray();
    console.log(user);
    dbHelper.close();
  }

  static async findAll() {
    const conn = await dbHelper.connect();
    const dbo = conn.db("test");
    const userCol = dbo.collection("user");
    const users = await userCol.find().toArray();
    console.log(users);
    dbHelper.close();
  }

  static async updateUserName(oldName, newName) {
    const conn = await dbHelper.connect();
    const dbo = conn.db("test");
    const userCol = dbo.collection("user");
    await userCol.updateOne( { username: oldName },{ $set: { username: newName}});
    const users = await userCol.find().toArray();
    console.log(users);
    dbHelper.close();
  }

  static async deleteOneByUserName(username) {
    const conn = await dbHelper.connect();
    const dbo = conn.db("test");
    const userCol = dbo.collection("user");
    await userCol.deleteOne( { username: username });
    const users = await userCol.find().toArray();
    console.log(users);
    dbHelper.close();
  }
}
module.exports = User;

业务执行

//index.js
const { insertOne, updateUserName, deleteOneByUserName } = require('./user_modal');
const User=require('./user_modal');

const Joe=new User('Joe','123');



(async ()=>{
    await User.insertOne(Joe);
    await User.updateUserName('Joe','KK');
    await User.deleteOneByUserName('KK');
})()

在这里插入图片描述


参考文档:
Node.js 连接 MongoDB
Nodejs中Mongodb使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值