數據存儲之IndexedDB

這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰數據庫

前言

在開發Web應用的過程當中,會設計一些數據的存儲需求,常見的存儲方式可能有:保存登陸態的Cookie;使用瀏覽器本地存儲的LocalStorageSessionStorage;客戶端數據持久化存儲方案涉及的WebSQLIndexedDB;直接存儲在本機的文件系統上等。跨域

往期文章查看:數據存儲之Cookie|8月更文挑戰瀏覽器

本章主要講述IndexedDB的特性以及打開/新建數據庫對數據增刪改查創建索引等基礎的操做。markdown


IndexedDB

IndexedDB是一種事物型數據庫系統,其事物型相似基於SQL的關係型數據庫管理系統(RDBMS),但其並不像RDBMS使用固定列表,而是一種基於JavaScript的面對對象的數據庫,更接近於NoSQL。它具備如下5個特色。異步

  • 存儲空間大,相比於LocalStorageSessionStorage根據不一樣瀏覽器可能不足10MB的,IndexedDB通常來講不會少於250MB,甚至沒有上限。
  • 支持事務,即知足事務操做所要求的的原子性,若在事務的一系列操做步驟中有一步失敗,整個事務就會取消,IndexedDB便會回滾到事務發生以前的狀態,不存在僅修改部分數據的狀況。
  • 支持多種數據模型IndexedDB採用對象倉庫存放數據,全部類型的數據均可以以鍵/值對的形式進行存儲,每條數據都由惟一的主鍵進行索引。存儲的類型不只能夠是對象、字符串,還能夠是二進制數據。
  • 同源約束,每一個網頁只能訪問其自身域名下的數據庫,不能跨域訪問。
  • 異步IndexedDB的數據操做不會阻塞瀏覽器主線程,這讓其能夠在讀寫大量數據時也不會拖慢網頁。

怎樣使用

打開或新建數據庫

使用IndexedDB的第一步就是打開或新建一個數據庫對象,具體代碼示例以下:svn

// 根據所指定的數據庫名稱去打開數據庫,若不存在則會新建數據庫,第二個參數爲數據庫的版本號
const request = window.indexedDB.open('my_indexeddb','1.0')
// 數據庫打開後的操做請求對象,經過三種事件來處理打開操做的結果
request.onerror = function(event) {
  console.log('數據庫打開失敗')
}
// 數據庫打開成功後,即可以經過request對象中的result屬性拿到數據庫對象
request.onsuccess = function(event){
  // 數據庫對象
  const db = request.result
}

/**
* 若是打開數據庫時指定的版本號大於實際版本號,則會觸發數據庫升級事件;
* 而新建數據庫必然會觸發該事件,一般新建數據庫以後的第一件事情即是建立對象倉庫對象,即建立表
*/

request.onupgradeneeded = function(event) {
  const db = event.target.event
  let objectStore
  // 判斷所要建立的日誌表log對象是否存在,不存在再進行建立
  if(!ob.objectStoreName.contains('logs')){
    // 建立日誌表對象,並指定主鍵
    objectStore = db.createObjectStore('logs', {keypath: 'id'})
  }
}
複製代碼

數據的增刪改查

新增數據須要先建立一個事務,而後使用objectStore()方法拿到IDBObjectStore後,經過add()方法進行數據的添加,示例代碼以下:post

// 以讀寫模式建立對日誌表logs的事務,而後經過對象存儲對象的add()方法添加一條數據
const request = db.transaction(['logs'], 'readwrite')
                .objectStore('logs')
                .add({id:1, log: 'hello IndexedDB', time: 1628003429409, user: 'Jack'})
// 可根據業務需求經過成功或失敗事件進行後續處理
request.onsuccess = function(event){console.log('新增數據成功')}
request.onerror= function(event){console.log('新增數據失敗')}
複製代碼

與新增數據相似,只需將add()方法替換成其餘相應的方法就可實現刪除、修改及查詢功能,刪除使用delete()方法,修改使用put()方法,查詢使用get()方法。另外在查找時還可對錶中數據進行遍歷,代碼示例以下:flex

// 建立對象存儲對象後,經過打開指針對象的異步方法進行遍歷
const objectStore = db.transaction('logs').objectStore('logs')
objectStore.openCursor().onsuccess = function(event) {
  // 每次獲得數據表中的一個數據項
  const cursor = event.target.rusult
  if(cursor){
    console.log('id:', cursor.key)
    console.log('log:', cursor.value.log)
    // 指針移動至下一個數據項
    cursor.continue()
  } else {
    console.log('已無更多數據')
  }
}
複製代碼

創建索引

創建索引可讓咱們搜索數據表中的任意字段值,若是沒有索引,則默認只能從主鍵進行取值。好比對於日誌表可在新建時對用戶user字段創建索引,代碼以下:url

objectStore.createIndex('user', 'user', { unique: false })
複製代碼

建立了索引後,即可使用user進行相關數據向的查找了,代碼示例以下:spa

const request = db.transation(['logs'], 'readonly')
                .objectStore('logs')
                .index('user')
                .get('Jack')
// 查找到數據結果後,經過事件處理方法進行相應處理
request.onsuccess = function(event) {
  const result = event.target.result
  if(result){
    // ...相應處理
  }
}
複製代碼

總結

IndededDB所包含的API相對複雜一些,但只需在基本操做流程中掌握其從不一樣是體重抽象出的對象接口,這些屍體對象接口包括:數據庫對象IDBDatabase對象倉庫對象IDBObjectStore索引對象IDBIndex事務對象IDBTransaction操做請求對象IDBRequest指針對象IDBCursor主鍵集合對象IDBKeyRange

相關文章
相關標籤/搜索