學習Lowdb小型本地JSON資料庫

  • 2019 年 10 月 3 日
  • 筆記

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' } ]

了解更多相關的知識,請看這裡