学习Lowdb小型本地JSON数据库
Lowdb是轻量化的基于Node的JSON文件数据库。对于构建不依赖服务器的小型项目,使用LowDB存储和管理数据是非常不错的选择。
一:lowdb 使用及安装
在项目中的根目录安装 lowdb 命令如下:
npm install --save-dev lowdb
lowdb是基于lodash构建的,因此我们可以使用任何 lodash 强大的函数。并且我们可以串联使用。
下面我们的目录结构比如是如下:
|--- lowdb
| |--- node_modules
| |--- app.js
| |--- package.json
然后我们在app.js 添加如下代码:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json');
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 0 }).write();
如上保存后,我们在命令行中执行 node app.js 后,会在我们的项目中的根目录下新建一个叫 db.json 文件,该文件代码变成如下所示:
{
"posts": [],
"user": {},
"count": 0
}
如上代码,引入 lowdb包,然后引入 lowdb 中的适配器 FileSync。
lowdb自带的适配器有:FileSync、FileAsync 和 LocalBrowser。分别有以下可选参数:
defaultValue: 文件不存在时的默认值。
serialize/deserialize: 文件被写之前和读之后的操作。
比如如下代码:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 0 }).write();
如上代码,如果我们的db.json 没有数据的时候 才会重新调用 db.defaults初始化数据,否则的话会使用本地存储的数据。我们可以更改 count 的值试试看,不管我们在node命令行中运行多少次,值都是一样的,但是当我们把 db.json内容删除掉后,我们再运行下,发现最新的内容被写入进去了。
如上代码,如果我们把上面的代码改成这样的如下:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => console.log(data),
deserialize: (data) => console.log(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
那么在命令行中运行下,第一次被写入之前 serialize 打印 为 {} 空对象。然后就执行 db.defaults 操作就会把对应的数据写入到 db.json 文件中,然后我们就会执行 deserialize 操作对文件进行读取,然后在命令行中会打印 { posts: [], user: {}, count: 30 }。 打印完成后,我们没有做任何操作后,最后我们再来查看下 db.json文件的内容变成了 undefined. 因此我们可以判定 serialize 和 deserialize 这两个操作完成后,他们也会对文件进行写入操作。如果没有值被写入或操作的话,那么文件内容就变为undefined。当文件变为undefined后,我们再执行上面的代码,可以看到 db.defaults({posts: [], user: {}, count: 30 }).write(); 这句代码是不会被写入的。那么我们可以猜想的到,这句代码的含义是会判断该文件 有没有内容,如果没有内容的话文件数据才会被写入,否则的话就不会执行任何操作。我们可以再把 db.json 文件内容全部删除掉,我们再运行下 node app.js 命令后,可以看到这个时候 数据才会被写入进去。
1. 设置数据
我们可以对 db.json 数据里面设置某个字段的数据,比如如下代码:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 设置数据
db.set("user.name", 'kongzhi').write();
然后我们的 db.json 数据变成如下了:
{"posts":[],"user":{"name":"kongzhi"},"count":30}
2. 获取数据
我们可以对json文件获取某个字段后的值,然后进行添加数据操作,或者删除数据操作,总之我们可以操作数据,如下代码:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 设置数据
db.set("user.name", 'kongzhi').write();
// get 数据, 然后添加一条数据进去,最后写入文档里面去。
db.get('posts').push({'id': 1, 'title': 'welcome to hangzhou' }).write();
我们的db.json 文件代码变成如下所示:
{"posts":[{"id":1,"title":"welcome to hangzhou"}],"user":{"name":"kongzhi"},"count":30}
3. 更新数据,我们可以对某条数据进行更新。如下代码所示:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 设置数据
db.set("user.name", 'kongzhi').write();
// get 数据, 然后添加一条数据进去,最后写入文档里面去。
// db.get('posts').push({'id': 1, 'title': 'welcome to hangzhou' }).write();
// 使用 update 更新数据 这里的n 就是 count 的默认值,在db.json中的count默认值为30, 最后写入进去
db.update('count', n => n + 1).write();
运行后 db.json 数据代码如下所示:
{"posts":[{"id":1,"title":"welcome to hangzhou"}],"user":{"name":"kongzhi"},"count":31}
注意:由于我们的 lowdb 基于 lodash 的,因此我们可以使用 lodash 中的所有方法和属性。
4. find 查找字段中数据
我们可以对 db.json 中的某个字段的数据进行查找。代码如下所示:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 设置数据
db.set("user.name", 'kongzhi').write();
// get 数据, 然后添加一条数据进去,最后写入文档里面去。
// db.get('posts').push({'id': 1, 'title': 'welcome to hangzhou' }).write();
// 使用 update 更新数据 这里的n 就是 count 的默认值,在db.json中的count默认值为30, 最后写入进去
db.update('count', n => n + 1).write();
// 查找数据
const value = db.get('posts').find({'id': 1}).value();
console.log(value);
假如我们的db.json 代码如下:
{"posts":[{"id":1,"title":"welcome to hangzhou"}],"user":{"name":"kongzhi"},"count":33}
因此我们通过 db.get('posts').find({'id': 1}).value() 后就可以获取到值了,如下所示:

5. lowdb 的API
1. low(adapter): 它返回一个具有特定属性和功能的 lodash.
2. db.[...].write()/.value(): write() 方法是写入数据,value()方法是读取数据。
3. db.getState()/.setState(): 获取/设置数据库的状态。
4. db._ 数据库的lodash的实列。我们可以使用这个来添加我们自己的函数或者第三方的mixins。比如 lodash-id(https://github.com/typicode/lodash-id)
mixins 的使用列子如下:
代码如下:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 使用 mixin 混合模式来扩展我们自己的方法
db._.mixin({
getSecondData: function(arr) {
return arr[1];
}
});
// 调用 getSecondData 方法 获取到 posts 第二条数据
const xx = db.get('posts').getSecondData().value();
console.log(xx);
假如我们的db.json 代码如下数据:
{
"posts":[
{"id":1,"title":"welcome to hangzhou"},
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
我们运行 node app.js 命令后,可以看到,我们可以获取到数组里面的第二条数据了,如下所示:

6. db.getState/db.setState 获取数据库状态/设置数据库的状态, 如下代码演示:
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const adapter = new FileSync('./db.json', {
serialize: (data) => JSON.stringify(data),
deserialize: (data) => JSON.parse(data)
});
const db = low(adapter);
db.defaults({posts: [], user: {}, count: 30 }).write();
// 获取数据库的状态
console.log(db.getState());
const newState = {}
db.setState(newState);
console.log('-----------');
console.log(db.getState());
db.json 假如数据如下:
{
"posts":
[
{"id":1,"title":"welcome to hangzhou"},
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
运行结果如下图所示:

7. 其他json数据操作
比如 db.json 数据如下所示:
{
"posts":
[
{"id":1,"title":"welcome to hangzhou"},
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
1. 检查db.json中有没有 'posts' 这个字段是否存在。如下测试代码:
db.has('posts').value(); // 如果有该字段就会返回 true, 否则的话,返回false.
2. 设置值 set
db.set('posts', []).write(); // 运行完成后,就会对 posts 字段设置为 空数组了 [];
3. 获取特定字段的值
db.get('posts').map('id').value(); // 执行完成后会返回 [1, 2]
4. 获取数量
db.get('posts').size().value(); // 返回该数组的长度为 2
5. 获取特定信息的值
db.get('posts[0].id').value(); // 就会返回 1.
6. 更新信息
db.get('posts')
.find({title: 'welcome to hangzhou'})
.assign({name: 'kongzhi'})
.write();
如上代码,我们可以看到,我们获取 posts这个字段,然后通过 find这个关键字去查找 {title: 'welcome to hangzhou'} 这样的,如果找到,就把 它改成 assign 里面的对象值。如果没有找到,就会在该对象里面添加该值,因此上面的结果返回如下:
{
"posts":[
{"id":1,"title":"welcome to hangzhou","name":"kongzhi"},
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
如果我们把上面的语句改成如下语句,就会更改对应的值了:
db.get('posts')
.find({name: 'kongzhi'})
.assign({name: 'xxx'})
.write();
那么结果就变成如下:
{
"posts":[
{"id":1,"title":"welcome to hangzhou","name":"xxx"},
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
7. 删除信息
db.get('posts')
.remove({name: 'xxx'})
.write();
那么结果就变为如下了:
{
"posts":[
{"id":2,"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
8. 移除属性
db.unset('posts[0].id').write();
那么结果变为如下了:
{"posts":[
{"title":"welcome to hangzhou"}
],
"user":{"name":"kongzhi"},
"count":33
}
9. 深拷贝
var xx = db.get('posts').cloneDeep().value();
console.log(xx); // 打印:[ { title: 'welcome to hangzhou' } ]
了解更多相关的知识,请看这里
学习Lowdb小型本地JSON数据库的更多相关文章
- 本地存储数据库indexedDB实现离线预览的功能
今天在学习<高级JS编程>,看到离线存储,cookie和session都十分的熟悉,但是书中还提到了indexedDB和webSQL(已废弃),indexedDB可以像mysql一样建表, ...
- HTML5本地存储和本地的数据库
一个网站如何能在客户的浏览器存储更多的数据呢? 在Html4的时代在浏览器端存储点网站个性化的数据,尤其是用户浏览器的痕迹,用户的相关数据等一般只能存储在Cookie中,但是大多是浏览器对于Cooki ...
- Xamarin android使用Sqlite做本地存储数据库
android使用Sqlite做本地存储非常常见(打个比方就像是浏览器要做本地存储使用LocalStorage,貌似不是很恰当,大概就是这个意思). SQLite 是一个软件库,实现了自给自足的.无服 ...
- golang学习笔记16 beego orm 数据库操作
golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...
- vue axios post不能本地json
vue 脚本架里axios post是不能本地json,GET可以 解决这个问题需要自己在node里写脚本: 在build里新建立fakedata.js var express = require(' ...
- vue 模拟后台数据(加载本地json文件)调试
首先创建一个本地json文件,放在项目中如下 { "runRedLight":{ "CurrentPage": 1, "TotalPages" ...
- 手把手教你vue配置请求本地json数据
本篇文章主要介绍了vue配置请求本地json数据的方法,分享给大家,具体如下:在build文件夹下找到webpack.dev.conf.js文件,在const portfinder = require ...
- django学习-10.django连接mysql数据库和创建数据表
1.django模型 Django对各种数据库提供了很好的支持,包括:PostgreSQL.MySQL.SQLite.Oracle. Django为这些数据库提供了统一的调用API. 我们可以根据自己 ...
- 访问本地json文件因跨域导致的问题
我使用jquery的getJSON的方法获取本地的json文件,并进行操作,获取json 数据代码如下: $.getJSON("invite_panel.json",functio ...
随机推荐
- 《ElasticSearch6.x实战教程》之复杂搜索、Java客户端(下)
第八章-复杂搜索 黑夜给了我黑色的眼睛,我却用它寻找光明. 经过了解简单的API和简单搜索,已经基本上能应付大部分的使用场景.可是非关系型数据库数据的文档数据往往又多又杂,各种各样冗余的字段,组成了一 ...
- JS系列1---节流,去抖(防抖)应用场景:intput请求优化,页面监听
在项目开发过程中经常遇到在input的change事件中发起请求,将用户最新输入的字符作为data传给后台,但是如果用户的输入频率过高,或者用户输入的字符还未拼成一个完整的字词,这时候发起请求会浪费网 ...
- 小白开学Asp.Net Core 《九》
小白开学Asp.Net Core <九> — — 前端篇(不务正业) 在<小白开学Asp.Net Core 三>中使用了X-admin 2.x 和 Layui将管理后端的界面重 ...
- 确保Web安全的HTTPS
HTTP在安全方面主要有以下不足: 1. 通信使用明文不加密,内容可能会被窃听:(TCP/IP就是可能被窃听的网络) 2. 不验证通信方的身份,因此有可能遭遇伪装: (无法判断请求或响应是否正确,是否 ...
- context创建过程解析(三)之deployDirectories
HostConfig.deployApps() //在监听到start事件类型,也就是StandardHost调用startInternal protected void deployApps() { ...
- http状态码 500-599
类比: 客户端:客人 服务器:便利店 http报文:中文语言+钱 500:服务器内部错误,无法完成请求 客户端:给我一瓶可乐 服务器:对不起,不能给你服务,本店昨天起火烧了 501:服务器不支持请求的 ...
- 用机智云做PWM占空比控制电机,物联网智能家居应用
因为是新申请的博客,所以申请了总想往里面加点东西,所以把我之前在机智云写的帖子复制了过来 (各位抱歉,由于之前上传的文件可能有错误,之前上传的文件PWM不能用,那么我又重新上传了一个文件,这个文件 ...
- Flask+APScheduler定时任务
1.安装依赖 pip install flask_apscheduler 2.使用定时任务 ```python from flask import Flask from flask_apschedul ...
- swift 分享share页面封装(功能按钮不同)
关于分享功能的页面应该有很多,写这篇swift版本的分享页面,根据不同模块可能分享的功能按钮不一样,引言: 想必大家都使用微博右上角更多按钮,会弹出如下的界面: 在开发中,可能针对同一个app的不同按 ...
- SpringMVC项目案例之---数据的获取与显示
数据的获取与显示 (一)功能 1.对用户输入的数据进行获取 2.将获取的数据显示到页面 3.使用了SpringMVC技术的注解方式 4.使用了过滤器,处理中文乱码问题 5.在web.xml中设置了访问 ...