04、electron数据的持久化存储--lowdb
转载声明:
本文为摘录自“简书”,版权归原作者所有。
温馨提示:
为了更好的体验,请点击原文链接进行浏览
摘录时间:
2021-09-12 12:37:08
electron毕竟是一个桌面应用,那么存储用户数据一定是必备的功能。为了方便操作和理解,选用了lowdb
数据库。
一、lowdb的优势
- 基于lodash开发的,有lodash的加持,用起来很顺手。
- 采用JSON为基本存储结构,不管是调用还是备份都很方便。
- 持续的维护,有不少好用的插件。
- 很关键的是同步操作,采用链式调用的写法,写起来有种jQuery的感觉。
- 用JSON存储的数据,更方便前端开发人员理解和使用。
二、准备工作
安装需要的插件库
# 安装数据库
yarn add lowdb # cnpm install --save lowdb
# 操作数据库文件,安装最新版本的运行时会报错,建议安装指定版本的
yarn add fs-extra@8.1.0 # cnpm install --save fs-extra@8.1.0
三、生成数据库文件并初始化数据
由于electron给main和renderder进程都置入了Node的fs模块,所以我们很方便的在两端都使用跟fs
相关的操作。而lowdb本质上就是通过fs来读写JSON文件实现的,正好符合我们的要求。下面我们来初始化一下
- 在
src/main
路径下新建datastore.js
文件。具体代码如下
import Datastore from 'lowdb'
import FileSync from 'lowdb/adapters/FileSync'
import path from 'path'
import fs from 'fs-extra'
import { app, remote } from 'electron'
const APP = process.type === 'renderer' ? remote.app : app // 根据process.type来分辨在哪种模式使用哪种模块
const STORE_PATH = APP.getPath('userData') // 获取electron应用的用户目录
// 我的是C:\Users\wsl\AppData\Roaming\Electron
// 判断路径是否存在,若不存在,就创建
if (process.type !== 'renderer') {
if (!fs.pathExistsSync(STORE_PATH)) {
fs.mkdirpSync(STORE_PATH)
}
}
// 初始化lowdb读写的json文件名以及存储路径
const adapter = new FileSync(path.join(STORE_PATH, '/data.json'))
const db = Datastore(adapter) // lowdb接管该文件
export default db // 暴露出去
数据库的存储路径不能放在static下面,因为项目打包后static会被编码,无法获取,即使不编码能获取到,也不允许更改。所以,直接放在C盘的用户数据里面就可以了。坑我替你们踩过了。
- 初始化数据库
// 初始化数据,若没有时,才会初始化
if (!db.has('array').value()) {
db.set('array', []).write()
}
if (!db.has('object').value()) {
db.set('object', {
key: 'value'
}).write()
}
if (!db.has('number').value()) {
db.set('number', 123).write()
}
生成的数据如下,可以直接打开更改,重启应用时,会重新获取最新数据
{
"array": [],
"object": {
"key": "value"
},
"number": 123
}
- 数据库的基本操作
要将更改保存进数据库文件,必须要在更改后调用write()方法。否则,应用重启后,之前的数据会丢失。
# 对象
db.set('object', { key: 'value' }).write() # 增加键值对
db.get('object').remove({ key: 'value' }) .write() # 删除
# 数组
db.get('array').push(value).write() # 将新项添加至数组的末尾
db.get('array').find(item => item.key == value).set('key', newValue).write() # 更新数组对象的键值对
- 在Vue中使用lowdb的便捷方法
将db挂在原型链上,这样我们就可以在项目里,用this.$db
的方法来使用lowdb了。
import db from '../datastore'
Vue.prototype.$db = db
- 存在的问题
main进程和renderer进程拿到的db都是应用打开时所读取的。在没有额外处理的情况下,在main进程拿到的内存里的db,和renderer拿到的内存里的db不是同一个db,也就是所谓的不是一个db的两份引用,而是一个db的两份拷贝。main进程对其进行的操作,renderer进程是不知道的。换句话说,main进程对db进行了任何读写操作,renderer拿到的db依然是当初应用打开时所读取的db。所以就会遇到main进程更新了数据,而renderer进程依然无法拿到新的数据。
解决方法:在所有的db操作的最开始,都重新读取一遍db的最新状态
db.read().get('xxx').value()
db.read().set('xxx','xyx')