IndexedDB 是一個基於 JavaScript 的面向對象的事務型數據庫。有了 LocalStorage
和 Cookies
,爲何還要推出 indexedDB
呢?其實對於在瀏覽器裏存儲數據,可使用 cookies
或 LocalStorage
,但它們都是比較簡單的技術,而 IndexedDB
提供了相似數據庫風格的數據存儲和使用方式。javascript
LocalStorage
是用 key-value
鍵值模式存儲數據,它存儲的數據都是字符串形式。若是你想讓 LocalStorage
存儲對象,你須要藉助 JSON.stringify()
能將對象變成字符串形式,再用 JSON.parse()
將字符串還原成對象,就是專門爲小數量數據設計的,因此它的 api 設計爲同步的。html
IndexedDB
很適合存儲大量數據,它的 API 是異步調用的。IndexedDB
使用索引存儲數據,各類數據庫操做放在事務中執行。IndexedDB
甚至還支持簡單的數據類型。IndexedDB
比 localstorage
強大得多,但它的 API 也相對複雜。對於簡單的數據,你應該繼續使用 localstorage
,但當你但願存儲大量數據時,IndexedDB
會明顯的更適合,IndexedDB
能提供你更爲複雜的查詢數據的方式。java
有了數據庫後咱們天然但願建立一個表用來存儲數據,但 indexedDB 中沒有表的概念,而是 objectStore,一個數據庫中能夠包含多個 objectStore,objectStore 是一個靈活的數據結構,能夠存放多種類型數據。也就是說一個 objectStore 至關於一張表,裏面存儲的每條數據和一個鍵相關聯。咱們可使用每條記錄中的某個指定字段做爲鍵值(keyPath),也可使用自動生成的遞增數字做爲鍵值(keyGenerator),也能夠不指定。選擇鍵的類型不一樣,objectStore 能夠存儲的數據結構也有差別。web
在 indexedDB 中,每個對數據庫操做是在一個事務的上下文中執行的。事務範圍一次影響一個或多個 object stores,你經過傳入一個 object store 名字的數組到建立事務範圍的函數來定義。例如:db.transaction(storeName, 'readwrite'),建立事務的第二個參數是事務模式。當請求一個事務時,必須決定是按照只讀仍是讀寫模式請求訪問。ajax
對 indexedDB 數據庫的每次操做,描述爲經過一個請求打開數據庫,訪問一個 object store,再繼續。IndexedDB API 天生是基於請求的,這也是 API 異步本性指示。對於你在數據庫執行的每次操做,你必須首先爲這個操做建立一個請求。當請求完成,你能夠響應由請求結果產生的事件和錯誤。數據庫
在 IndexedDB 大部分操做並非咱們經常使用的調用方法,返回結果的模式,而是請求—響應的模式,所謂異步 API 是指並非這條指令執行完畢,咱們就可使用 request.result 來獲取 indexedDB 對象了,就像使用 ajax 同樣,語句執行完並不表明已經獲取到了對象,因此咱們通常在其回調函數中處理。api
IDBFactory:數據庫工廠,負責打開或者建立數據庫數組
IDBIndex:數據庫表的索引cookie
IDBRequest:機會是全部 indexedDB 操做的返回值,indexedDB 操做請求
var db; // 全局的indexedDB數據庫實例。 //1\. 獲取IDBFactory接口實例(文檔地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBFactory) var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB; if (!indexedDB) { console.log('你的瀏覽器不支持IndexedDB'); } // 2\. 經過IDBFactory接口的open方法打開一個indexedDB的數據庫實例 // 第一個參數: 數據庫的名字,第二個參數:數據庫的版本。返回值是一個:IDBRequest實例,此實例有onerror和onsuccess事件。 var IDBOpenDBRequest = indexedDB.open('demoDB', 1); // 3\. 對打開數據庫的事件進行處理 // 打開數據庫成功後,自動調用onsuccess事件回調。 IDBOpenDBRequest.onsuccess = function(e) {}; // 打開數據庫失敗 IDBOpenDBRequest.onerror = function(e) { console.log(e.currentTarget.error.message); }; // 第一次打開成功後或者版本有變化自動執行如下事件:通常用於初始化數據庫。 IDBOpenDBRequest.onupgradeneeded = function(e) { db = e.target.result; // 獲取到 demoDB對應的 IDBDatabase實例,也就是咱們的數據庫。 if (!db.objectStoreNames.contains(personStore)) { //若是表格不存在,建立一個新的表格(keyPath,主鍵 ; autoIncrement,是否自增),會返回一個對象(objectStore) // objectStore就至關於數據庫中的一張表。IDBObjectStore類型。 var objectStore = db.createObjectStore(personStore, { keyPath: 'id', autoIncrement: true }); //指定能夠被索引的字段,unique字段是否惟一。類型: IDBIndex objectStore.createIndex('name', 'name', { unique: true }); objectStore.createIndex('phone', 'phone', { unique: false }); } console.log('數據庫版本更改成: ' + dbVersion); };
indexedDB 的增刪改查的操做須要放到一個事務中進行(推薦)
// 建立一個事務,類型:IDBTransaction,文檔地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 經過事務來獲取IDBObjectStore var store = transaction.objectStore(personStore); // 往store表中添加數據 var addPersonRequest = store.add({ name: '老馬', phone: '189111833', address: 'aicoder.com' }); // 監聽添加成功事件 addPersonRequest.onsuccess = function(e) { console.log(e.target.result); // 打印添加成功數據的 主鍵(id) }; // 監聽失敗事件 addPersonRequest.onerror = function(e) { console.log(e.target.error); };
// 建立一個事務,類型:IDBTransaction,文檔地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 經過事務來獲取IDBObjectStore var store = transaction.objectStore(personStore); var person = { id: 6, name: 'lama', phone: '515154084', address: 'aicoder.com' }; // 修改或者添加數據。 第一參數是要修改的數據,第二個參數是主鍵(可省略) var updatePersonRequest = store.get(6); // 監聽添加成功事件 updatePersonRequest.onsuccess = function(e) { // var p = e.target.result; // 要修改的原對象 store.put(person); }; // 監聽失敗事件 updatePersonRequest.onerror = function(e) { console.log(e.target.error); };
// 建立一個事務,類型:IDBTransaction,文檔地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 經過事務來獲取IDBObjectStore var store = transaction.objectStore(personStore); store.delete(6).onsuccess = function(e) { console.log(刪除成功!) };
// 建立一個事務,類型:IDBTransaction,文檔地址: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction var transaction = db.transaction(personStore, 'readwrite'); // 經過事務來獲取IDBObjectStore var store = transaction.objectStore(personStore); store.get(6).onsuccess = function(e) { console.log(刪除成功!) };
var trans = db.transaction(personStore, 'readwrite'); var store = trans.objectStore(personStore); var cursorRequest = store.openCursor(); cursorRequest.onsuccess = function(e) { var cursor = e.target.result; if (cursor) { var html = template('tbTmpl', cursor.value); document.getElementById('tbd').innerHTML += html; cursor.continue(); // 遊標繼續往下 搜索,重複觸發 onsuccess方法,若是到最後返回null } };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="./lib/art_template.js"></script> </head> <body> <table> <tr> <td> <label for="name">用戶名</label> </td> <td> <input type="text" name="name" id="name"> </td> </tr> <tr> <td> <label for="phone">電話</label> </td> <td> <input type="text" name="phone" id="phone"> </td> </tr> <tr> <td> <label for="address">地址</label> </td> <td> <input type="text" name="address" id="address"> </td> </tr> </table> <input type="button" value="添加用戶" id="btnAdd" onclick="addPerson()"> <table> <thead> <tr> <th>id</th> <th>name</th> <th>address</th> <th>phone</th> <th>編輯</th> </tr> </thead> <tbody id="tbd"> </tbody> </table> <script id="tbTmpl" type="text/html">