瀏覽器數(shù)據(jù)庫(kù)IndexDB

1. 前言

最近剛?cè)肼氃诳葱马?xiàng)目的代碼,學(xué)習(xí)了很多新的代碼封裝思路和模塊化的思想。而且也了解到了IndexedDB數(shù)據(jù)庫(kù)的使用方法,開(kāi)一篇文章來(lái)總結(jié)下IndexedDB在項(xiàng)目中的使用。

2. IndexedDB

2-1. IndexedDB是什么

通俗地說(shuō),IndexedDB就是瀏覽器提供的本地?cái)?shù)據(jù)庫(kù),它可以被網(wǎng)頁(yè)腳本創(chuàng)建和操作。

2-2. 為什么要使用它

以往做網(wǎng)頁(yè)存儲(chǔ),我們一般使用cookielocalStorage或者sessionStorage。但是這兩種方法一個(gè)存儲(chǔ)的空間有限,一個(gè)也只能建立很簡(jiǎn)單的對(duì)象設(shè)置和獲取屬性。而IndexedDB不僅能存儲(chǔ)大量數(shù)據(jù),而且還能建立索引和提供查找接口。在大型項(xiàng)目中會(huì)有很大的優(yōu)勢(shì)。

關(guān)于IndexedDB的特點(diǎn)和基本概念阮老師的博客寫(xiě)的很清楚。我這里不做概述。本篇文章只是為了記錄下我現(xiàn)在的項(xiàng)目中是如何使用IndexedDB,介紹基本的使用方法。瀏覽器數(shù)據(jù)庫(kù)

3. 使用方法

3-1. 打開(kāi)或者新建數(shù)據(jù)庫(kù)

// 獲取indexedDB數(shù)據(jù)對(duì)象
const indexedDB  = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB
// 打開(kāi)或者新建數(shù)據(jù)庫(kù)
/**
 * @param {string} databaseName: 打開(kāi)/新建的數(shù)據(jù)庫(kù)名稱(chēng)
 * @param {string} version: 數(shù)據(jù)庫(kù)版本號(hào)
 */
let dbRequest = window.indexedDB.open(databaseName, version);

3-2. 設(shè)置不同的處理方法

打開(kāi)數(shù)據(jù)庫(kù)后我們能拿到一個(gè)IndexDBRequest對(duì)象,這個(gè)對(duì)象有三個(gè)處理事件的方法,來(lái)處理打開(kāi)或者新增數(shù)據(jù)庫(kù)的操作結(jié)果

  1. success事件
dbRequest.onsuccess = event => {
  console.log("數(shù)據(jù)庫(kù)打開(kāi)成功");
  // 數(shù)據(jù)庫(kù)的實(shí)例對(duì)象
  const db = event.target.result;
}
  1. error事件
dbRequest.onerror = event => {
  console.log("數(shù)據(jù)庫(kù)打開(kāi)失敗");
}
  1. upgradeneeded事件
  • 對(duì)于打開(kāi)數(shù)據(jù)庫(kù)來(lái)說(shuō)如果指定的版本大于數(shù)據(jù)庫(kù)的實(shí)際版本就會(huì)這個(gè)數(shù)據(jù)庫(kù)升級(jí)事件,一般來(lái)說(shuō)不會(huì)處理這個(gè)
// 打開(kāi)已有數(shù)據(jù)庫(kù)如果指定的version高于當(dāng)前數(shù)據(jù)的version
window.indexedDB.open(databaseName, version);
dbRequest.onupgradeneeded = event => {
  console.log("數(shù)據(jù)庫(kù)需要升級(jí)");
}
  • 對(duì)于新建數(shù)據(jù)庫(kù),沒(méi)有版本,新建的時(shí)候就會(huì)直接觸發(fā)這個(gè)事件,通常我們會(huì)在這個(gè)事件中區(qū)新增數(shù)據(jù)庫(kù)表和索引。
dbRequest.onupgradeneeded = event => {
     // 通過(guò)事件對(duì)象的`target.result`創(chuàng)建新的數(shù)據(jù)庫(kù)表
     const db = event.target.result;
     // 創(chuàng)建前先判斷該數(shù)據(jù)庫(kù)表是否存在
     if (!db.objectStoreNames.contains("test")) {
        // 創(chuàng)建名為`test`的數(shù)據(jù)庫(kù)表并指定主鍵為`id`
        let objectStore = db.createObjectStore("test", { keyPath: "id" });  
        // 如果數(shù)據(jù)記錄里面沒(méi)有合適作為主鍵的屬性,那么可以讓 IndexedDB 自動(dòng)生成主鍵。
        // let objectStore = db.createObjectStore("test", { autoIncrement: true });

        // 創(chuàng)建索引
        /**
         * @param {string} 索引名稱(chēng)
         * @param {string} 索引所在的屬性
         * @param {object} 配置對(duì)象: 說(shuō)明該屬性是否包含重復(fù)的值
         */
        objectStore.createIndex("id", "id", { unique: true });
        objectStore.createIndex("value", "value", { unique: true });
     }
 };

3-3. 操作數(shù)據(jù)

操作數(shù)據(jù)分為新增,讀取,更新,刪除等。這些操作都需要通過(guò)事務(wù)完成。

// 打開(kāi)數(shù)據(jù)庫(kù)開(kāi)始操作數(shù)據(jù)
dbRequset.onsuccess = event => {
  // 新建事務(wù)
  // 新建時(shí)必須指定表格名稱(chēng)和操作模式("只讀"或"讀寫(xiě)")
  const trans = db.transaction(["test"], "readwrite");
  // 拿到IDBObjectStore對(duì)象
  const dictStore = trans.objectStore("test");
  // 通過(guò)IDBObjectStore對(duì)象操作數(shù)據(jù)

  // 讀取數(shù)據(jù)
  const getResp = disStore.get("1");
  // 新增數(shù)據(jù)
  const addResp = disStore.add({ id: 1, value: "test"});
  // 更新數(shù)據(jù)
  const putResp = disStore.put({ id: 1, value: "test1"});
  // 刪除數(shù)據(jù)
  const deleteResp = disStore.delete(1);

  // 上述幾種操作數(shù)據(jù)庫(kù)的方法都會(huì)返回一個(gè)連接對(duì)象
  // 通過(guò)監(jiān)聽(tīng)返回的連接對(duì)象來(lái)判斷是否操作成功
   getResp.onerror = function(event) {
     console.log('事務(wù)失敗');
   };

   getResp.onsuccess = function( event) {
      if (request.result) {
        console.log('value: ' + request.result.value);
      } else {
        console.log('未獲得數(shù)據(jù)記錄');
      }
   };
}

3-4. 使用索引

我們?cè)谏厦鎸?duì)value字段建立了索引

objectStore.createIndex("value", "value", { unique: true });

所以我們可以通過(guò)索引value去查找數(shù)據(jù)了

  // 也要先創(chuàng)建事務(wù)指定為只讀
  const trans = db.transaction(["test"], "readonly");
  // 拿到IDBObjectStore對(duì)象
  const dictStore = trans.objectStore("test");
  // 拿到連接對(duì)象
  let request = dictStore.index("value").get("test");
  request.onsuccess = function(event) {
      if (event.target.result) {
        console.log(event.target.result);
      } else {
        console.log('未獲得數(shù)據(jù)記錄');
      }
   };

最近項(xiàng)目中用到了很多新技術(shù),微前端,發(fā)布組件,瀏覽器數(shù)據(jù)庫(kù)等等,我目前也在一邊學(xué)習(xí)一邊總結(jié)。如果這篇文章對(duì)大家有幫助的話點(diǎn)個(gè)贊唄????

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容