IndexedDB
是一種可讓你在用戶瀏覽器中持久存儲數據的方法,對於須要存儲大量數據或者離線的web應用均可以考慮使用,相比已經被廢棄的WebSQL
,目前來看是IndexedDB將來一種的趨勢,而且兼容性比較友好(見下圖),若是儲存有限的localStorage
(具體大小看各家瀏覽器支持),不能知足你當前的使用需求,能夠考慮使用IndexedDB。
IndexedDB的存儲空間取決於硬盤大小和瀏覽器限制規則,正常狀況必定會遠遠大於localStorage的廣泛5M。
另外IndexedDB也聽從同源協議
(same-origin policy),只能訪問同域中存儲的數據。web
*數據來源於 caniuse數據庫
索引(indexes)
、表(tables)
、指針(cursors)
這些都必須依賴於事物,另外事物自己具備生存週期,只能在生存週期內使用,而且事物只能自動提交,不能夠手動操做。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 //更新數據庫對象 }
在數據庫第一次建立的時候,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 }) } }
插入
須要關注點 建立事物 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對象屬性
是由IDBRequest接口返回的事件處理函數的訪問結果集,結果集來自對數據庫和數據庫對象發起的異步查詢。咱們全部對IndexedDB數據庫的讀寫操做所有都要經過request的方式來實現。request對象初始時不包括任何關於操做結果的信息,當request上的事件觸發時,能夠經過IDBRequest實例上的事件處理函數訪問相關信息。IDBCursor
接口返回一個遊標,可以用於遍歷數據庫中的記錄。遊標包含一個源,指向須要遍歷的索引或者對象存儲區。它在所屬區間範圍內有一個位置,能夠根據記錄key的順序遞增或遞減方向移動。遊標使應用程序可以異步處理在遊標範圍內的全部記錄,同時容許在同一時間擁有無數個遊標。blog
由於數據存在用戶本地,當發生用戶主動去清除數據,瀏覽器處於隱私模式退出,用戶硬盤容量到達上限,硬盤文件發生損壞等狀況下使用都會受影響。