IndexedDB快速入門

IndexedDB概述

為什么要用IndexedDB?

1.大量數(shù)據(jù)儲存在客戶端,這樣可以減少從服務器獲取數(shù)據(jù)的次數(shù),直接從本地獲取數(shù)據(jù)。
2.現(xiàn)有的瀏覽器數(shù)據(jù)儲存方案,都不適合儲存大量數(shù)據(jù):
Cookie 的大小不超過4KB,且每次請求都會發(fā)送回服務器
LocalStorage 在 2.5MB 到 10MB 之間(各家瀏覽器不同)
...

IndexedDB是什么?

1.IndexedDB 就是瀏覽器提供的本地數(shù)據(jù)庫
2.IndexedDB 允許儲存大量數(shù)據(jù)(一般來說不少于 250MB),提供各種API,功能強大。
3.異步操作,防止大量數(shù)據(jù)的讀寫導致拖慢網(wǎng)頁的現(xiàn)象

indexedDB對象

1.數(shù)據(jù)庫


名為databaseName的數(shù)據(jù)庫

2.對象倉庫:每個數(shù)據(jù)庫包含若干個對象倉庫。它類似于關系型數(shù)據(jù)庫的表格。
3.數(shù)據(jù)記錄:對象倉庫保存的是數(shù)據(jù)記錄。
4.索引:為了加速數(shù)據(jù)的檢索,可以在對象倉庫里面,為不同的屬性建立索引。
5.事務:數(shù)據(jù)記錄的讀寫和刪改,都要通過事務完成。
6.指針


名為person的倉庫對象

api的基本使用

1.打開數(shù)據(jù)庫:indexedDB.open()

IndexedDB.open()方法返回一個 IDBRequest 對象。這個對象通過三種事件error、success、upgradeneeded,處理打開數(shù)據(jù)庫的操作結(jié)果
打開數(shù)據(jù)庫的執(zhí)行順序:
數(shù)據(jù)庫存在 ? error/ success : upgradeneeded => error/ success

 // 1.打開數(shù)據(jù)庫
    openDB () {
      return new Promise((resolve, reject) => {
        let db
        const request = this.indexedDB.open('databaseName', 1) // 事務對象  databaseName:數(shù)據(jù)庫的名字 version:數(shù)據(jù)庫的版本
        request.onsuccess = function (event) {
          db = event.target.result // 數(shù)據(jù)庫對象
          console.log('數(shù)據(jù)庫打開成功')
          resolve(db)
        }

        request.onerror = function (event) {
          console.log('數(shù)據(jù)庫打開報錯')
        }

        request.onupgradeneeded = function (event) { // 數(shù)據(jù)庫創(chuàng)建或升級的時候會觸發(fā)
          console.log('onupgradeneeded')
        }
      })
    },

2.新建/升級數(shù)據(jù)庫:upgradeneeded 事件

request.onupgradeneeded = function (event) { // 數(shù)據(jù)庫創(chuàng)建或升級的時候會觸發(fā)
          console.log('onupgradeneeded')
          db = event.target.result // 數(shù)據(jù)庫對象
          var objectStore
          if (!db.objectStoreNames.contains('person')) {
            objectStore = db.createObjectStore('person', { keyPath: 'id' }) // 創(chuàng)建表
            // objectStore = db.createObjectStore('person', { autoIncrement: true }) // 創(chuàng)建表
            objectStore.createIndex('name', 'name', { unique: false }) // 創(chuàng)建索引 可以讓你搜索任意字段
            objectStore.createIndex('address', 'address', { unique: false })
            objectStore.createIndex('nameAddr', ['name', 'address'], { unique: false })
            objectStore.createIndex('flag', 'flag', { unique: false })
          }
        }

(1)objectStore = db.createObjectStore('person', { keyPath: 'id' })新建對象倉庫(即新建表),主鍵(key)是默認建立索引的屬性,比如,數(shù)據(jù)記錄是{ id: 1, name: '張三' },那么id屬性可以作為主鍵
(2)objectStore = db.createObjectStore('person', { autoIncrement: true })新建對象倉庫(即新建表),數(shù)據(jù)記錄里面沒有合適作為主鍵的屬性,那么可以讓 IndexedDB 自動生成主鍵
(3)objectStore.createIndex('flag', 'flag', { unique: false })創(chuàng)建索引,可以讓你搜索任意字段;三個參數(shù)分別為索引名稱、索引所在的屬性、配置對象(說明該屬性是否包含重復的值)

3.新增數(shù)據(jù):add()

// 2.新增數(shù)據(jù) db:數(shù)據(jù)庫實例 storename:倉庫名稱 data:數(shù)據(jù)
    addData (db, storename, data) {
      var request = db.transaction([storename], 'readwrite') // 事務對象 指定表格名稱和操作模式("只讀"或"讀寫")
        .objectStore(storename) // 倉庫對象
        .add(data)

      request.onsuccess = function (event) {
        console.log('數(shù)據(jù)寫入成功')
      }

      request.onerror = function (event) {
        console.log('數(shù)據(jù)寫入失敗')
        throw new Error(event.target.error)
      }
    },

(1)db.transaction([storename], 'readwrite')新建時必須指定表格名稱和操作模式("只讀"或"讀寫")。

4.查詢數(shù)據(jù)

(1)主鍵讀取數(shù)據(jù)
讀取數(shù)據(jù)也是通過事務完成。
下邊代碼中,objectStore.get()方法用于讀取數(shù)據(jù),參數(shù)是主鍵的值。

// 3.通過主鍵讀取數(shù)據(jù) storename:表名稱 key 主鍵值
    getDataByKey: function (db, storename, key) {
      return new Promise((resolve, reject) => {
        var transaction = db.transaction([storename]) // 事務
        var objectStore = transaction.objectStore(storename) // 倉庫對象
        var request = objectStore.get(key)

        request.onerror = function (event) {
          console.log('事務失敗')
        }

        request.onsuccess = function (event) {
          console.log('主鍵查詢結(jié)果: ', request.result)
          resolve(request.result)
        }
      })
    },

(2)游標查詢記錄,遍歷數(shù)據(jù)
遍歷數(shù)據(jù)表格的所有記錄,要使用指針對象 IDBCursor。
下面代碼中,新建指針對象的openCursor()方法是一個異步操作,所以要監(jiān)聽success事件。

// 4.通過游標查詢記錄 db 數(shù)據(jù)庫實例  storename 倉庫/表名稱
    cursorGetData: function (db, storename) {
      let list = []
      var store = db.transaction(storename, 'readwrite') // 事務
        .objectStore(storename) // 倉庫對象
      var request = store.openCursor() // 指針對象
      request.onsuccess = function (e) {
        var cursor = e.target.result
        if (cursor) { // 必須要檢查
          list.push(cursor.value)
          cursor.continue()// 遍歷了存儲對象中的所有內(nèi)容
        } else {
          console.log('游標查詢結(jié)果:', list)
        }
      }
    },

(3)索引讀取數(shù)據(jù)
可以通過索引意義搜索任意字段,也就是說從任意字段拿到數(shù)據(jù)記錄。如果不建立索引,默認只能搜索主鍵。
假定新建表格的時候,對indexName字段建立了索引。

 getDataByIndex: function (db, storename, indexName, indexValue) {
      var store = db.transaction(storename, 'readwrite') // 事務
        .objectStore(storename) // 倉庫對象
      var request = store.index(indexName) // 索引對象
        .get(indexValue)
      request.onerror = function () {
        console.log('事務失敗')
      }
      request.onsuccess = function (e) {
        var result = e.target.result
        console.log('索引查詢結(jié)果:', result)
      }
    },

(4)索引游標查詢記錄
與索引查詢的區(qū)別:
索引查詢:查詢滿足條件的第一條數(shù)據(jù)
索引和游標查詢:滿足條件的所有數(shù)據(jù)

// 6.通過索引游標查詢記錄  db:數(shù)據(jù)庫實例 storename 倉庫/表名稱  indexName:索引名  indexValue:索引值
    cursorGetDataByIndex: function (db, storename, indexName, indexValue) {
      let list = []
      var store = db.transaction(storename, 'readwrite').objectStore(storename) // 倉庫對象
      var request = store.index(indexName) // 索引對象
        .openCursor(IDBKeyRange.only(indexValue)) // 指針對象
      request.onsuccess = function (e) {
        var cursor = e.target.result
        if (cursor) { // 必須要檢查
          list.push(cursor.value)
          cursor.continue()// 遍歷了存儲對象中的所有內(nèi)容
        } else {
          console.log('游標索引查詢結(jié)果:', list)
        }
      }
      request.onerror = function (e) {
      }
    }

5.更新數(shù)據(jù)

put()方法根據(jù)主鍵自動更新相應數(shù)據(jù)記錄

// 7.更新數(shù)據(jù) db:數(shù)據(jù)庫實例 tableName:表名稱 data:數(shù)據(jù)
    updateData: function (db, storename, data) {
      var request = db.transaction([storename], 'readwrite') // 事務對象
        .objectStore(storename) // 倉庫對象
        .put(data)

      request.onsuccess = function () {
        console.log('數(shù)據(jù)更新成功')
      }

      request.onerror = function () {
        console.log('數(shù)據(jù)更新失敗')
      }
    },

6.刪除數(shù)據(jù)

(1)主鍵刪除
IDBObjectStore.delete()方法用于刪除記錄

// 8.刪除數(shù)據(jù) db:數(shù)據(jù)庫實例 tableName:表名稱 id:主鍵值
    deleteData: function (db, storename, id) {
      var request = db.transaction([storename], 'readwrite') // 事務
        .objectStore(storename) // 倉庫對象
        .delete(id)

      request.onsuccess = function () {
        console.log('數(shù)據(jù)刪除成功')
      }

      request.onerror = function () {
        console.log('數(shù)據(jù)刪除失敗')
      }
    },

(2)索引和游標刪除指定的數(shù)據(jù)
匹配到滿足條件的數(shù)據(jù)后,cursor.delete()方法用于刪除數(shù)據(jù)記錄

 // 9.通過索引和游標刪除指定的數(shù)據(jù) db:數(shù)據(jù)庫實例  storename:表名稱   indexName:索引名  indexValue:索引值
    cursorDeleteData: function (db, storename, indexName, indexValue) {
      var store = db.transaction(storename, 'readwrite').objectStore(storename) // 倉庫對象
      var request = store.index(indexName) // 索引對象
        .openCursor(IDBKeyRange.only(indexValue)) // 指針對象
      request.onsuccess = function (e) {
        var cursor = e.target.result
        var deleteRequest
        if (cursor) {
          deleteRequest = cursor.delete()// 請求刪除當前項
          deleteRequest.onerror = function () {
            console.log('游標刪除該記錄失敗')
          }
          deleteRequest.onsuccess = function () {
            console.log('游標刪除該記錄成功')
          }
          cursor.continue()
        }
      }
      request.onerror = function (e) {
      }
    },

7.關閉數(shù)據(jù)庫

 // 10.關閉數(shù)據(jù)庫 db:數(shù)據(jù)庫實例
    closeDB: function (db) {
      db.close()
      console.log('數(shù)據(jù)庫已關閉')
    },

8.刪除數(shù)據(jù)庫

注意要先關閉數(shù)據(jù)庫再刪除,否則刪除失敗

// 11.刪除數(shù)據(jù)庫 dbname:數(shù)據(jù)庫名稱
    deletedb: function () {
      var self = this
      let deleteRequest = self.indexedDB.deleteDatabase('databaseName')
      deleteRequest.onerror = function (event) {
        console.log('刪除失敗')
      }
      deleteRequest.onsuccess = function (event) {
        console.log('刪除成功')
      }
    },

小結(jié)

1.了解基本概念
2.API靈活使用
掌握這些就基本上掌握了IndexedDB的基本使用啦

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

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

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