Node + Ts + Mongodb 增删改查封装

俗言有道,自奉必减几分方好,处世能退一步为高。
之前有很多的前后端开发,数据库其实是一个项目运行的必须的一环,也是很重要的一环。
数据库千千万,合适的到底有哪些?

数据库有哪些

跳过废话

  • 关系型数据库
    • Oracle
    • MySQL
  • 非关系型数据库
    • NoSQL
  • 键值存储数据库(key-value)
    • Memcached
    • Redis
    • MemcacheDB
  • 列存储(Column-oriented)数据库
    • Cassandra
    • HBase
  • 面向文档(Document-Oriented)数据库
    • MongoDB
    • CouchDB
  • 图形数据库
    • Neo4J
    • InforGrid

MongoDB

https://www.mongodb.com/home

几句话。

不管是kv的内存型redies,还是文档型的mongodb,上手都很都很简单,而且,文档型数据库跟json很像啊,那就更容易理解了,再加上性能还凑合,就他了呗,而且还有mongoose这种玩意,写着毫无压力,个把小时就上手了
敲黑板!时间就是金钱啊,先上了再说玩会了这个流程,是什么数据库不重要,都是store,根据配置切不同实现就完事。至于后面要考虑的存和取的性能和场景,不需要一开始就过度考虑。

妄论一下。

1.Node在io并发处理比较擅长,mongodb也是擅长读写的,两者这方面很契合,mongodb在大数据方面也比较擅长。
2.mongodb是文档数据,数据结构是bson,也可以说是json,而众所周知json是来源于JavaScript object,nodejs又是以js为编程语言。

Js为底层语言

很直观的体现了,在进入Mongo时,执行1 + 1会返回2,dddd

看到这里,其实也跃跃欲试了,如何像博主一样花费30分钟就可以玩得转它?

我知道你很急,但是你先别急。

安装流程

很保姆级了,往下看。

下载。

安装。

无需配置环境变量。

能理解到这一步,其实对shell这类,还有系统这类有一定认识了,mongo.exe其实就是一个cmd程序。

我的bin文件夹

pic

打开目录下的终端,这里不管是cmd还是terminal都可以

pic

先别急着一步步操作,看教程是为了学会,请耐心通读本段落

mongod.exe是创建mongodb的进程,也就是打开数据库的程序

我在D:/创建了文件夹Databases/Mongodb

pic
pic

刚创建文件夹肯定不会像我一样有文件。。。

mongod.exe --dbpath "D:/Databases/Mongodb/"

执行完后,你会发现你的文件夹里面生成了文件。

然后,
打开数据库。。。

mongosh.exe是一个可以操作mongodb的命令行程序

mongosh.exe
pic

到这里,你拥有了一个Mongodb数据库。

使用方法

创建数据库

尝试使用一个自定义的数据库:

> use test_db
switched to db test_db
> db
test_db
>
> show dbs
admin    40.00 KiB
config   72.00 KiB
local    72.00 KiB
test_db   8.00 KiB
>

“为什么我use的test_db不在里面?”

> db.test_db.insert({"name":"测试"})
DeprecationWarning: Collection.insert() is deprecated. Use insertOne, insertMany, or bulkWrite.
{
  acknowledged: true,
  insertedIds: { '0': ObjectId("63917571c6696a553b3fc68c") }
}
> show dbs
admin    40.00 KiB
config   72.00 KiB
local    72.00 KiB
test_db   8.00 KiB
>

出现了。
在这一步,Mongodb会在你插入数据的时候自动创建数据库。(很方便)

删除数据库

> db.dropDatabase()
{ ok: 1, dropped: 'test_db' }
>

集合

列出

show collections

创建

db.createCollection(name, options)

options

字段 类型 描述
capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。当该值为 true 时,必须指定 size 参数。
autoIndexId 布尔 3.2 之后不再支持该参数。(可选)如为 true,自动在 _id 字段创建索引。默认为 false。
size 数值 (可选)为固定集合指定一个最大值,即字节数。如果 capped 为 true,也需要指定该字段。
max 数值 (可选)指定固定集合中包含文档的最大数量。

删除

db.collection.drop()

文档

于集合下的一个子函数,可以理解为集合的下一级,而文档内存储的就是业务逻辑中的主要内容

插入

{% codeblock lang:js %}
db.COLLECTION_NAME.insert(document)

db.COLLECTION_NAME.save(document)
{% endcodeblock %}

更新

{% codeblock lang:js %}
db.collection.update(
,
,
{
upsert: ,
multi: ,
writeConcern:
}
)
{% endcodeblock %}

DB类封装

{% codeblock lang:ts %}
import * as mongodb from 'mongodb';
import { DBI } from './interfaces';

export class Db implements DBI {
public client: mongodb.MongoClient | undefined;
public db: mongodb.Db | undefined;

static instance: Db | null;

static getInstance() {
    if (!Db.instance) throw "No Event!"
    return this.instance;
}

constructor(DB_CONN_STRING: string, DB_NAME: string) {
    this.connection(DB_CONN_STRING, DB_NAME);
}

/**
 * 插入数据
 * @param collectionName 集合名称
 * @param doc 内容
 * @returns 
 */
public insert<T = mongodb.Document>(collectionName: string, doc: mongodb.OptionalId<T>): Promise<mongodb.InsertOneResult<mongodb.Document>> {
    return new Promise<mongodb.InsertOneResult<mongodb.Document>>(async (resolve, reject) => {
        try {
            this.db?.collection(collectionName).insertOne(doc).then(resolve).catch(err => {
                throw err;
            });
        } catch (err) {
            reject(false);
        }
    });
}

/**
 * 插入多数据
 * @param collectionName 集合名称
 * @param docs[] 内容数组
 * @returns 
 */
public insertMany<T = mongodb.Document>(collectionName: string, docs: mongodb.OptionalId<T>[]): Promise<mongodb.InsertManyResult<mongodb.Document>> {
    return new Promise<mongodb.InsertManyResult<mongodb.Document>>(async (resolve, reject) => {
        try {
            this.db?.collection(collectionName).insertMany(docs).then(resolve).catch(err => {
                throw err;
            });
        } catch (err) {
            reject(false);
        }
    });
}

public delete<T = mongodb.Document>(collectionName: string, filter: mongodb.Filter<T>): Promise<mongodb.DeleteResult> {
    return new Promise<mongodb.DeleteResult>(async (resolve, reject) => {
        try {
            this.db?.collection(collectionName).deleteOne(filter).then(resolve).catch(err => {
                throw err;
            });
        } catch (err) {
            reject(false);
        }
    }).catch(err => {
        return err;
    });
}

public deleteMany<T = mongodb.Document>(collectionName: string, filter: mongodb.Filter<T>): Promise<mongodb.DeleteResult> {
    return new Promise<mongodb.DeleteResult>(async (resolve, reject) => {
        try {
            this.db?.collection(collectionName).deleteMany(filter).then(resolve).catch(err => {
                throw err;
            });
        } catch (err) {
            reject(false);
        }
    }).catch(err => {
        return err;
    });
}

public update<T = mongodb.Document>(collectionName: string, filter: mongodb.Filter<T>, update: mongodb.UpdateFilter<T>): Promise<mongodb.UpdateResult> {
    return new Promise<mongodb.UpdateResult>(async (resolve, reject) => {
        try {
            this.db?.collection(collectionName).updateOne(filter, update).then(resolve).catch(err => {
                throw err;
            });
        } catch (err) {
            reject(false);
        }
    }).catch(err => {
        return err;
    });
}

public find<T = mongodb.Document>(collectionName: string, filter: mongodb.Filter<T>): Promise<any[]> {
    return new Promise<any>(async (resolve, reject) => {
        try {
            resolve(this.db?.collection(collectionName).find(filter));
        } catch (err) {
            reject(false);
        }
    }).catch(err => {
        return err;
    });
}

public aggregate(_collectionName: string, _pipeline: object[]): Promise<any[]> {
    throw new Error('Method not implemented.');
}

private connection(DB_CONN_STRING: string, DB_NAME: string): Promise<mongodb.MongoClient> {
    return new Promise<mongodb.MongoClient>(async (resolve, reject) => {
        try {
            if (!this.client) {

                const client: mongodb.MongoClient = new mongodb.MongoClient(DB_CONN_STRING);
                await client.connect();
                this.db = client.db(DB_NAME);
                this.client = client;
                console.log("[Mongodb] class inited.");
            }
            resolve(this.client);
        } catch (err) {
            reject(err);
        }
    });
}

}
{% endcodeblock %}

JS-SDK引入

ts_mongodb-2023-01-08-23-26-42

emmmmmm内心复杂。
照理来说微信不该对组件编程陌生,这里居然还用半嵌入式页面开发。
既来之,则安之,我把它转为对象引入到项目,这部分有很多大佬都做了,因为没什么技术门槛。