node操作本地数据库-NeDB方案


NeDB是使用Nodejs实现的一个NoSQL嵌入式数据库操作模块,可以充当内存数据库,也可以用来实现本地存储,甚至可以在浏览器中使用。查询方式比较灵活,支持使用正则、比较运算符、逻辑运算符、索引以及JSON深度查询等。
NeDB嵌入到了应用程序进程中,消除了与客户机服务器配置相关的开销,在运行时,也只需要较少的内存开销,使用精简代码编写,速度更快。其APIMongoDB的一个子集,可以通过这些接口轻松管理应用程序数据,而不依靠原始的文档文件。
具有简单、轻量、速度快等特点,由于嵌入式数据库存储总数据量最好要控制在1GB以内,所以适合在不需要大量数据处理的应用系统中使用(比如使用nw.js等实现的桌面应用程序、并发量不大的系统等)。

一、安装NeDB数据库

cnpm install nedb --save

二、建立数据库链接

import NeDB from 'nedb';
const DB = new NeDB({
    autoload: true,
    filename: ('path/to/datafile/data.db')
})

三、操作数据库

  1. 新增数据
    语法:
    db.insert(doc, callback)
    作用:
    插入文档数据(文档相当于mysql表中的一条记录)。如果文档不包含_id字段,NeDB会自动生成一个,该字段是16个字符长度的数字字符串。该字段一旦确定,就不能被更改。
    参数:
    doc: 支持String, Number, Boolean, Date, null, array以及object类型。如果该字段是undefined类型,将不会被保存,这里和MongoDB处理方式有点不同,MongoDB会将undefined转换为null进行存储。字段名称不能以"$"开始,也不能包含"."。
    callback(可选): 回调函数,包含参数err以及newDocerr是报错,newDoc是新插入的文档,包含它的_id字段。
    示例如下:
DB.insert({ name: 'cuiht', age: 25 }, function (err, doc) {
    if (err) {
        console.log(err);
        return;
    }
    console.log(doc);
});
  1. 查询数据
    语法:
    db.find(query, callback)ordb.findOne(query, callback)
    作用:
    db.find(query, callback)查询符合条件的文档集,db.findOne(query, callback)查询符合条件的一个文档
    参数:
    queryobject类型,查询条件。支持使用比较运算符($lt, $lte, $gt, $gte, $in, $nin, $ne), 逻辑运算符($or, $and, $not, $where), 正则表达式进行查询。
    callback(可选): 回调函数,包含参数err以及docserr是报错,docs是查询到的文档集。
    示例如下:
DB.find({ age: 20}, (err, docs) => {
    if (err) {
        console.log(err);
        return;
    }
    console.log(docs);
});
DB.findOne({ _id: 'rlflxrv0OXkew9z4' }, (err, docs) => {
    if (err) {
        console.log(err);
        return;
    }
    console.log(docs);
});
  1. 更新数据
    语法:
    db.update(query, update, options, callback)
    作用:
    根据update参数的规则,更新匹配到query的结果集。
    参数:
    query: 与findfindOnequery参数的用法一致
    update: 指定文档更改规则。该参数可以是一个新的文档,也可以是一套修饰符,两者不能同时使用。使用修饰符时,如果需要更改的字段不存在,将会自动创建。可用的修饰符有$set(改变字段值), $unset(删除某一字段), $inc(增加某一字段), $min/$max(改变字段值,传入值需要小于/大于当前值), 还有一些用在数组上的修饰符,$push, $pop, $addTopSet, $pull, $each, $slice,具体用法如下示例。
    options: object类型。muti(默认false),是否允许修改多条文档;upsert(默认为false),如果query没有匹配到结果集,有两种情况需要考虑,一个是update是一个简单的对象(不包含任何修饰符),另一种情况是带有修饰符,对第一种情况会直接将该文档插入,对第二种情况会将通过修饰符更改后的文档插入;
    callback(可选): 参数(err, numAffected, affectedDocuments, upsert)。numAffected:被影响的文档个数;affectedDocuments:更新后的文档。
    注意:_id不能被修改
    示例如下:
DB.update({ _id: 'rlflxrv0OXkew9z4' }, { $set: { name: 'cuiht_update' } }, function (err, data) {
    if (err) {
        console.log(err);
        return;
    }
    console.log(data);
});
  1. 删除数据
    语法:
    db.remove(query, options, callback)
    作用:
    根据options配置删除所有query匹配到的文档集。
    参数:
    query: 与findquery参数的用法一致
    options: 只有一个可用。muti(默认false),允许删除多个文档。
    callback: 可选,参数: err, numRemoved
    示例如下:
DB.remove({ _id: 'rlflxrv0OXkew9z4' }, {}, function (err, data) {
    if (err) {
        console.log(err);
        return;
    }
    console.log(data);
});

四、使用案例

注意,这里是在vue中的使用案例。
  1. 新建文件src/DB/index.js
/*
 * @Author: cuiht
 * @Date: 2022-04-22 13:38:40
 * @LastEditors: cuiht
 * @LastEditTime: 2022-04-22 16:40:46
 * @Description: 数据库链接 及 数据库操作方法封装
 */
import NeDB from 'nedb';

const DBList = {
    history: new NeDB({
        autoload: true,
        // 指定数据库文件路径
        filename: ('path/to/datafile/data.db')
    })
}, DBserve = (arg) => {
    return new Promise((resolve, reject) => {
        const { DBname = '', order = '', option = {} } = arg;
        if (!DBname) {
            return reject({
                code: 0,
                msg: '未获取数据库名!'
            })
        }
        const _DB = DBList[DBname];
        if (!order) {
            return reject({
                code: 0,
                msg: '未获取到指令!'
            })
        }
        switch (order) {
            case 'insert':
                _DB.insert({
                    ...option,
                    createTime: new Date
                }, function (err, data) {
                    if (err) {
                        return reject({
                            code: 0,
                            msg: err
                        })
                    }
                    return resolve({
                        code: 200,
                        msg: "新增成功!",
                        data,
                    })
                });
                break;
            case 'find':
                _DB.find(option).sort({ createTime: -1 }).exec(function (err, data) {
                    if (err) {
                        return reject({
                            code: 0,
                            msg: err
                        })
                    }
                    return resolve({
                        code: 200,
                        msg: "查询列表成功!",
                        data,
                    })
                });
                break;
            case 'findOne':
                _DB.findOne(option, function (err, data) {
                    if (err) {
                        return reject({
                            code: 0,
                            msg: err
                        })
                    }
                    return resolve({
                        code: 200,
                        msg: "查询成功!",
                        data,
                    })
                });
                break;
            case 'update':
                if (!option?._id) {
                    return reject({
                        code: 0,
                        msg: '未获取到id'
                    })
                }
                _DB.update({ _id: option._id }, { $set: option }, function (err, data) {
                    if (err) {
                        return reject({
                            code: 0,
                            msg: err
                        })
                    }
                    return resolve({
                        code: 200,
                        msg: "更新成功!",
                        data,
                    })
                });
                break;
            case 'remove':
                if (!option?._id) {
                    return reject({
                        code: 0,
                        msg: '未获取到id'
                    })
                }
                _DB.remove({ _id: option._id }, {}, function (err, data) {
                    if (err) {
                        return reject({
                            code: 0,
                            msg: err
                        })
                    }
                    return resolve({
                        code: 200,
                        msg: "删除成功!",
                        data,
                    })
                });
                break;
            default:
                break;
        }
    })
}

export default DBserve;
  1. 新建src/network/historyServes.js
*
 * @Author: cuiht
 * @Date: 2022-04-22 13:37:11
 * @LastEditors: cuiht
 * @LastEditTime: 2022-04-22 16:42:41
 * @Description: 调用数据库方法封装
 */
import DBserve from '@/db'

export const
    // 新增记录
    historyAdd = data => DBserve({
        DBname: 'history',
        order: 'insert',
        option: data
    }),
    // 查询记录列表
    historyList = data => DBserve({
        DBname: 'history',
        order: 'find',
        option: data
    }),
    // 查询记录
    historyGet = data => DBserve({
        DBname: 'history',
        order: 'findOne',
        option: data
    }),
    // 修改记录
    historyUpt = data => DBserve({
        DBname: 'history',
        order: 'update',
        option: data
    }),
    // 删除记录
    historyDel = data => DBserve({
        DBname: 'history',
        order: 'remove',
        option: data
    });
  1. 新建一个vue页面。
<!--
 * @Author: cuiht
 * @Date: 2022-04-21 15:38:03
 * @LastEditors: cuiht
 * @LastEditTime: 2022-04-22 16:43:27
 * @Description: 使用示例
-->
<template>
  <div id="text-page">
    <table class="list">
      <tr>
        <td><button @click="Add">新增</button></td>
      </tr>
      <tr v-for="item in list" :key="item._id">
        <td>
          {{ item }}
        </td>
        <td style="width: 150px">
          <button @click="Upt(item)">修改</button>
          <button @click="Del(item)">删除</button>
          <button @click="Get(item)">查看</button>
        </td>
      </tr>
    </table>
  </div>
</template>

<script>
import {
  historyAdd,
  historyList,
  historyGet,
  historyUpt,
  historyDel,
} from "@/network/historyServes";
export default {
  name: "test",
  data() {
    return {
      list: [],
    };
  },
  mounted() {
    this.List();
  },
  methods: {
    Add() {
      const reqData = {
        age: this.list.length + 1,
        name: "cuiht-" + new Date().getTime(),
      };
      historyAdd(reqData).then((res) => {
        console.log(res);
        if (res.code !== 200) {
          return;
        }
        this.List();
      });
    },
    List() {
      historyList().then((res) => {
        console.log(res);
        if (res.code !== 200) {
          return;
        }
        this.list = res.data;
      });
    },
    Get(item) {
      historyGet({
        _id: item._id,
      }).then((res) => {
        console.log(res);
        if (res.code !== 200) {
          return;
        }
        alert(JSON.stringify(res.data));
      });
    },
    Upt(item) {
      const reqData = {
        _id: item._id,
        age: this.list.length + 1,
        name: "undate-" + new Date().getTime(),
      };
      historyUpt(reqData).then((res) => {
        console.log(res);
        if (res.code !== 200) {
          return;
        }
        this.List();
      });
    },
    Del(item) {
      historyDel({
        _id: item._id,
      }).then((res) => {
        console.log(res);
        if (res.code !== 200) {
          return;
        }
        this.List();
      });
    },
  },
};
</script>

<style lang="scss">
#text-page {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
}
</style>
效果图

参考文章:NeDB—Node嵌入式数据库 w3cschool

我们最终都要远行,最终都要跟稚嫩的自己告别。

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

推荐阅读更多精彩内容