04、electron数据的持久化存储--lowdb

来源:简书 分类: 文章浏览史 发布时间:2021-09-12 12:37:08 最后更新:2021-09-12 浏览:173
转载声明:
本文为摘录自“简书”,版权归原作者所有。
温馨提示:
为了更好的体验,请点击原文链接进行浏览
摘录时间:
2021-09-12 12:37:08

electron毕竟是一个桌面应用,那么存储用户数据一定是必备的功能。为了方便操作和理解,选用了lowdb数据库。

一、lowdb的优势

  1. 基于lodash开发的,有lodash的加持,用起来很顺手。
  2. 采用JSON为基本存储结构,不管是调用还是备份都很方便。
  3. 持续的维护,有不少好用的插件。
  4. 很关键的是同步操作,采用链式调用的写法,写起来有种jQuery的感觉。
  5. 用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文件实现的,正好符合我们的要求。下面我们来初始化一下

  1. 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盘的用户数据里面就可以了。坑我替你们踩过了。

  1. 初始化数据库
// 初始化数据,若没有时,才会初始化
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
}
  1. 数据库的基本操作
    要将更改保存进数据库文件,必须要在更改后调用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() # 更新数组对象的键值对
  1. 在Vue中使用lowdb的便捷方法
    将db挂在原型链上,这样我们就可以在项目里,用this.$db的方法来使用lowdb了。
import db from '../datastore'
Vue.prototype.$db = db
  1. 存在的问题
    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')
参考文档

1.引入基于Lodash的JSON数据库lowdb

php技术微信