這是我參與8月更文挑戰的第3天,活動詳情查看:8月更文挑戰數據庫
在開發Web
應用的過程當中,會設計一些數據的存儲需求,常見的存儲方式可能有:保存登陸態的Cookie
;使用瀏覽器本地存儲的LocalStorage
和SessionStorage
;客戶端數據持久化存儲方案涉及的WebSQL
和IndexedDB
;直接存儲在本機的文件系統上等。跨域
往期文章查看:數據存儲之Cookie|8月更文挑戰瀏覽器
本章主要講述IndexedDB
的特性以及打開/新建數據庫、對數據增刪改查、創建索引等基礎的操做。markdown
IndexedDB
是一種事物型數據庫系統,其事物型相似基於SQL
的關係型數據庫管理系統(RDBMS),但其並不像RDBMS使用固定列表,而是一種基於JavaScript
的面對對象的數據庫,更接近於NoSQL
。它具備如下5個特色。異步
LocalStorage
和SessionStorage
根據不一樣瀏覽器可能不足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。