學習Lowdb小型本地JSON數據庫

Lowdb是輕量化的基於Node的JSON文件數據庫。對於構建不依賴服務器的小型項目,使用LowDB存儲和管理數據是很是不錯的選擇。html

一:lowdb 使用及安裝node

在項目中的根目錄安裝 lowdb 命令以下:git

npm install --save-dev lowdb

lowdb是基於lodash構建的,所以咱們可使用任何 lodash 強大的函數。而且咱們能夠串聯使用。
下面咱們的目錄結構好比是以下:github

|--- 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 文件,該文件代碼變成以下所示:npm

{
  "posts": [],
  "user": {},
  "count": 0
}

如上代碼,引入 lowdb包,而後引入 lowdb 中的適配器 FileSync。
lowdb自帶的適配器有:FileSync、FileAsync 和 LocalBrowser。分別有如下可選參數:json

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內容刪除掉後,咱們再運行下,發現最新的內容被寫入進去了。app

如上代碼,若是咱們把上面的代碼改爲這樣的以下:

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

瞭解更多相關的知識,請看這裏

相關文章
相關標籤/搜索