HTML5 -- 瀏覽器數據緩存 -- indexedDB

IndexedDB是一種可讓你在用戶的瀏覽器內持久化存儲數據的方法,爲web應用提供了豐富的查詢功能,使咱們的應用在在線和離線都能正常工做。web

因爲 IndexedDB 自己的規範還在持續演進中,當前的 IndexedDB 的實現仍是使用瀏覽器前綴。在規範更加穩定以前,瀏覽器廠商對於標準 IndexedDB API 可能都會有不一樣的實現。可是一旦你們對規範達成共識的話,廠商就會不帶前綴標記地進行實現。實際上一些實現已經移除了瀏覽器前綴:IE 10,Firefox 16 和 Chrome 24。數據庫

若是你但願在仍舊使用前綴的瀏覽器中測試你的代碼, 可使用下列代碼:瀏覽器

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange

要注意的是使用前綴的實現可能會有問題,或者是實現的並不完整,也可能遵循的仍是舊版的規範。所以不建議在生產環境中使用。咱們更傾向於明確的不支持某一瀏覽器,而不是聲稱支持可是實際運行中卻出問題:函數

function hasIndexedDB () {
   if (!window.indexedDB) {
      return true;
   }
}

打開數據庫:測試

// 打開咱們的數據庫
var request = window.indexedDB.open("MyTestDatabase");

indexedDB打開數據庫的方法如上,必須進行request,indexedDB只有一個open方法,上面的代碼表示打開了一個"MyTestDatabase"的數據庫,該方法能夠接受第二個參數:fetch

// 打開咱們的數據庫,版本號爲1
var request = window.indexedDB.open("MyTestDatabase", 1);

第二個參數的版本號爲整數,當前打開的版本號不能比現有的版本號小,不然會報錯。spa

幾乎全部咱們產生的請求咱們在處理的時候首先要作的就是添加成功和失敗處理函數:code

var db;
request.onerror = function(event) { // Do something with request.errorCode! }; request.onsuccess = function(event) {
  db = event.target.result;
// Do something with request.result! };

request還有一個回掉方法:blog

request.onupgradeneeded = function(event) {
  var _db = event.target.result;
  // Do something with request.result!
};

onupgradeneeded方法是隻有在版本號升級的狀況下才會執行(若是當前版本號爲1,當咱們在打開open(storeName, 2)時,onupgradeneeded就會執行)。索引

下面是整個數據庫的操做流程:

當咱們建立一個新的數據表時,咱們首先要在onupgradeneeded方法中建立表:

// 只有在onupgradeneeded方法中有效
var createObjectStore = function (db, storeName) {
if (!db.objectStoreNames.contains(storeName)) { db.createObjectStore(storeName, { keyPath: 'id', autoIncrement: true }) console.log("createObjectStore:" + storeName + ",成功!") } }

刪除表:

// 刪除Store(在onupgradeneeded裏調用)
deleteObjectStore (db, storeName) {
    console.log('deleteObjectStore')
    if (db.objectStoreNames.contains(storeName)) {
      db.deleteObjectStore(storeName)
      console.log("deleteObjectStore:" + storeName + ",成功!")
    }
}

表中添加數據:

var students: [
        { id: 1001, name: "Byron", age: 24 }, 
        { id: 1002, name: "Frank", age: 30 }, 
        { id: 1003, name: "Aaron", age: 26 }, 
        { id: 1004, name: "Casper", age: 26 }
]
// 添加數據方法 在onsuccess中執行
var addData = function (db, storeName) {
    console.log('addData success')
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = null

    for (let i = 0; i < students.length; i++) {
      request = store.add(tstudents[i])
      request.onerror = function () {
        console.error('數據庫已有該數據!')
      } 
      request.onsuccess = function () {
        console.log('添加成功')
      }
    }
}

注意,在執行addData方法的時候,要確保已執行createObjectStore方法,不然會報錯。添加完以後瀏覽器顯示:

 

查詢數據:

  // 查詢數據(根據關鍵詞keyValue)
  var getDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readonly')
    let store = transaction.objectStore(storeName)

    let request = store.get(keyValue)
    request.onsuccess = function (e) {
      let result = e.target.result
      console.log(result)
    }
  }

 更新數據:

  // 更新數據
  var updateDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = store.get(keyValue)
    request.onsuccess = function (e) {
      let student = e.target.result
      student.age = 35
      store.put(student)
      console.log(student)
    }
  }

刪除數據:

  // 刪除數據
  var deleteDataByKey = function (db, storeName, keyValue) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let result = store.delete(keyValue)
    result.onsuccess = function () {
      console.log('刪除成功')
    }
    result.onerror = function () {
      console.log('刪除失敗')
    }
  }

清空表:

  // 清空store
  var clearObjectStore = function (db, storeName) {
    let transaction = db.transaction(storeName, 'readwrite')
    let store = transaction.objectStore(storeName)
    let request = store.clear()
    request.onsuccess = function () {
      console.log('清空成功')
    }
    request.onerror = function () {
      console.log('清空失敗')
    }
  }

關閉數據庫:

  // 關閉database
  var closeIDB = function (db) {
    db.close()
    console.log('關閉')
  }

刪除數據庫:

  // 刪除database
  var deleteIDB = function (db) {
    console.log('刪除')
    window.indexedDB.deleteDatabase(db)
  }

新增表(帶索引):

  // 新增Store--帶索引(在onupgradeneeded裏調用)
  var createObjectStoreWidthIndex = function (db, storeName) {
    if (!db.objectStoreNames.contains(storeName)) {
      let store = db.createObjectStore(storeName, {
        keyPath: 'id'
      })
      store.createIndex('nameIndex', 'name', {
        unique: true
      })
      store.createIndex('ageIndex', 'age', {
        unique: false
      })
      console.log("createObjectStore:" + storeName + ",成功!")
    }
  }

成功以後瀏覽器端顯示:

獲取數據的方法:

  // 獲取數據(根據索引)
  var getDataByIndex = function (db, storeName) {
    let transaction = db.transaction(storeName, 'readonly')
    let store = transaction.objectStore(storeName)
    let index = store.index('nameIndex')
    index.get('Byron').onsuccess = function (e) {
      let student = e.target.result
      console.log(student)
    }
  }
  // 使用遊標
  var fetchStoreByCursor = function (db, storeName) {
    let transaction = db.transaction(storeName)
    let store = transaction.objectStore(storeName)
    let request = store.openCursor() // 查詢所有
    request.onsuccess = function (e) {
      let cursor = e.target.result
      if (cursor) {
        let student = cursor.value
        console.log(student)
        cursor.continue()
      }
    }
  }
  // 索引與遊標結合
  var getDataByMultiple = function (db, storeName) {
    // 指定遊標範圍
    // IDBKeyRange.only(value):只獲取指定數據
    // IDBKeyRange.lowerBound(value,isOpen):獲取比value大的數據(isOpen: true不包含value, false包含value)
    // IDBKeyRange.upperBound(value,isOpen):獲取比value小的數據(isOpen: true不包含value, false包含value)
    // IDBKeyRange.bound(value1,value2,isOpen1,isOpen2)
    let transaction = db.transaction(storeName)
    let store = transaction.objectStore(storeName)
    let index = store.index('ageIndex')
    index.openCursor(IDBKeyRange.bound(24, 30, true, true)).onsuccess = function (e) {
      let cursor = e.target.result
      if (cursor) {
        let s = cursor.value
        console.log(s)
        cursor.continue()
      }
    }
  }

若是咱們須要手動更新版本,咱們先要將indexedDB關閉,而後再打開新版本的數據庫:

  var updataVersion = function (db, storeName, version) {
    closeIDB(db)
    console.log('更新版本', storeName, version)
    openIDB(storeName, version)
  }
相關文章
相關標籤/搜索