IndexedDB入門

IndexedDB簡介

IndexedDB是一種可讓你在用戶瀏覽器中持久存儲數據的方法,對於須要存儲大量數據或者離線的web應用均可以考慮使用,相比已經被廢棄的WebSQL,目前來看是IndexedDB將來一種的趨勢,而且兼容性比較友好(見下圖),若是儲存有限的localStorage(具體大小看各家瀏覽器支持),不能知足你當前的使用需求,能夠考慮使用IndexedDB。
IndexedDB的存儲空間取決於硬盤大小和瀏覽器限制規則,正常狀況必定會遠遠大於localStorage的廣泛5M。
另外IndexedDB也聽從同源協議(same-origin policy),只能訪問同域中存儲的數據。web

目前各大瀏覽器對於IndexedDB的兼容

indexedDB各大瀏覽器支持

*數據來源於 caniuse數據庫

IndexedDB主要特色

  • 鍵值對(Key-Value)存儲: key具備惟一性,每一個key都對應一個value,key能夠是對象自身的屬性,value可以直接支持複雜的對象結構,另外key能夠是二進制對象。
  • 支持事物(transaction): IndexedDB是事務模式的數據庫,一切操做都發生在事務中,索引(indexes)表(tables)指針(cursors)這些都必須依賴於事物,另外事物自己具備生存週期,只能在生存週期內使用,而且事物只能自動提交,不能夠手動操做。
  • 異步: IndexedDB的API不經過return語句返回數據,而是須要回調函數來接受數據。執行API時,會向數據庫發送一個請求。當操做完成時,數據庫會以事件的方式進行通知你,同時事件的類型會告訴你這個操做是否成功。
  • 面向對象: indexedDB不是用二維表來表示集合的關係型數據庫。

基礎操做

1.打開/新建 數據庫

indexedDB.open( databaseName, version )
databaseName: 數據庫的名字,若是當前數據庫不存在則就會新建,若存在就是打開。
version: 數據庫的版本,可省略,若省略,新增時默認爲1,打開時默認爲當前版本。
如今建立一個新的數據庫瀏覽器

window.indexedDB.open('firstDB')

indexedDB.open()會返回一個IDBRequest對象( IDBRequest對象表示打開的數據庫鏈接,使用open()deleteDatabase()都會返回這個對象,對於數據庫的操做都是基於這個對象 )
在執行open操做後咱們須要關注IDBRequest對象的三個事件,success 打開數據庫成功、upgradeneeded 數據庫升級(當前指定的版本大於實際版本)、error 打開數據庫失敗。異步

const dbName = "firstDB"
let messageList = [],
    request, db
request = window.indexedDB.open(dbName, 1)
request.onerror = function(event) { 
  //錯誤處理
  console.error('數據庫異常')
}
request.onsuccess = function(event) { 
  //成功
  db = request.result //獲取數據庫對象
}
request.onupgradeneeded = function(event) { 
  //版本變動
  db = event.target.result //更新數據庫對象
}

2.建立對象倉庫

在數據庫第一次建立的時候,version經歷了從無到有的變動,因此會觸發onupgradeneeded事件.
須要關注點 1.keyPath主動設置主鍵,2.createIndex建立索引。函數

const dbName = "firstDB"
let messageList = [],
    request, db
(function() {
  'use strict'
  if (!('indexedDB' in window)) {
    //檢查當前瀏覽器是否支持indexedDB
    alert("Your browser doesn't support a stable version of IndexedDB.")
    return
  }
  request = window.indexedDB.open(dbName, 1)
})()

request.onerror = function(event) { 
  //錯誤處理
  console.error('數據庫異常')
}
request.onsuccess = function(event) { 
  //成功
  db = request.result //獲取數據庫對象
}
request.onupgradeneeded = function(event) { 
  //版本變動
  db = event.target.result //更新數據庫對象
  let objectStore
  if(!db.objectStoreNames.contains('message')) { //檢查是否存在message 
    //不存在則建立message keyPath主動設置主鍵 { keyPath: 'id' } autoIncrement自動生成主鍵
    //新建索引 參數分別爲索引名稱、索引所在的屬性、配置對象 unique是否容許重複值
    objectStore = db.createObjectStore('message',{ autoIncrement: true } ) 
    objectStore.createIndex('time', 'time', { unique: true }) 
    objectStore.createIndex('content', 'content', { unique: false })
  }
}

3.插入、讀取、遍歷、更新、刪除數據

插入
須要關注點 建立事物 transaction() 第一個參數 涉及操做的objectStore
第二個參數 操做類型 可省略 默認只讀 readonly只讀 readwrite讀寫spa

function writeData(params) {
  //建立事物 第一個參數 涉及的objectStore 
  //第二個參數 操做類型 可省略 默認只讀 readonly只讀  readwrite讀寫
  let req = db
    .transaction(['message'], 'readwrite')
    .objectStore('message')
    .add(params)
  req.onsuccess = function (event) {
    console.info('寫入成功')
  }
  req.onerror = function (event) {    
    console.error('寫入失敗: ' + event.srcElement.error.message )
  }
}

讀取、查找指針

function readData() {
  let transaction = db.transaction(['message']),
      objectStore = transaction.objectStore('message'),
      req = objectStore.get(1)
  req.onsuccess = function() {
    if(req.result) {
      //讀取成功
      console.log(req.result)
    }
  }
  req.onerror = function() {
    console.error('讀取失敗')
  }
}
function findData(key, value) {
  let transaction = db.transaction(['message'], 'readonly'),
      store = transaction.objectStore('message'),
      index = store.index(key), //對應的key
      req = index.get(value) //對應查找的值
  req.onsuccess = function(event) { //操做成功
    let result = event.target.result
    if(result) { //存在結果
      console.log(result)
    }
  }
}

遍歷數據、獲取所有數據code

function traversalData() {
  let objectStore = db.transaction('message').objectStore('message')
  // openCursor(range, direction) range 對象來限制被檢索的項目的範圍, direction能夠指定你但願進行迭代的方向
  objectStore.openCursor().onsuccess = function(event) {
    let cursor = event.target.result
    if(cursor) {
      messageList.push(cursor.value)
      cursor.continue() //繼續執行
    }
    else {
      console.info('獲取完畢')
    }
  }
}
function readAllData() {
  //一次性獲取所有數據
  let objectStore = db.transaction('message').objectStore('message'),
      allRecords = objectStore.getAll()
  allRecords.onsuccess = function() {
    messageList = allRecords.result
  }
}

更新、刪除對象

function updateData(params) {
  let req = db
  .transaction(['message'], 'readwrite')
  .objectStore('message')
  .put(params)
  req.onsuccess = function(event) {
    // 數據已更新
  }
  req.onerror = function(event) {
    // 錯誤處理
  }
}
function deleteData(key) {
  let req = db
  .transaction(['message'], 'readwrite')
  .objectStore('message')
  .delete(key)
  req.onsuccess = function(event) {
    console.info('數據刪除成功')
  }

}

IDBRequest對象、IDBCursor對象概念強化

IDBRequest對象屬性是由IDBRequest接口返回的事件處理函數的訪問結果集,結果集來自對數據庫和數據庫對象發起的異步查詢。咱們全部對IndexedDB數據庫的讀寫操做所有都要經過request的方式來實現。request對象初始時不包括任何關於操做結果的信息,當request上的事件觸發時,能夠經過IDBRequest實例上的事件處理函數訪問相關信息。
IDBCursor 接口返回一個遊標,可以用於遍歷數據庫中的記錄。遊標包含一個源,指向須要遍歷的索引或者對象存儲區。它在所屬區間範圍內有一個位置,能夠根據記錄key的順序遞增或遞減方向移動。遊標使應用程序可以異步處理在遊標範圍內的全部記錄,同時容許在同一時間擁有無數個遊標。blog

提醒

由於數據存在用戶本地,當發生用戶主動去清除數據,瀏覽器處於隱私模式退出,用戶硬盤容量到達上限,硬盤文件發生損壞等狀況下使用都會受影響。

相關文章
相關標籤/搜索