本地存儲主要有如下幾種:數據庫
因爲 WebSQL 在標準上還存在爭議,而 localStorage 實現數據分頁、查詢比較複雜,最終考慮使用了 IndexedDB 來知足需求。後端
var wxbDB = { name : "wxb", version: 1, db : null };
此處咱們定義了一個數據庫對象,包括name
數據庫名稱,version
數據庫的版本,以及 db
數據對象。數據結構
function initDB(dbObj) { dbObj.version = dbObj.version || 1; var request = indexedDB.open(dbObj.name, dbObj.version); request.onerror = function (e) { console.log(e.currentTarget.error.message); }; request.onsuccess = function (e) { dbObj.db = e.target.result; }; request.onupgradeneeded = function (e) { var thisDB = e.target.result; if (!thisDB.objectStoreNames.contains("material")) { var objStore = thisDB.createObjectStore("material", {keyPath: "id", autoIncrement: true}); objStore.createIndex("wxid", "wxid", {unique: true}); } if (!thisDB.objectStoreNames.contains("account")) { var objStore = thisDB.createObjectStore("account", {keyPath: "id", autoIncrement: true}); objStore.createIndex("wxid", "wxid", {unique: true}); objStore.createIndex("nickName", "nickName", {unique: false}); } }; }
indexedDB.open
方法能夠建立或者打開一個 IndexedDB
,並返回 IDBOpenDBRequest
對象。併發
IDBOpenDBRequest
對象除了onerror
和 onsuccess
,還有一個相似回調函數句柄 onupgradeneeded
。這個句柄在咱們請求打開的數據庫的版本號和已經存在的數據庫版本號不一致的時候調用。函數
indexedDB.open
方法的第二個可選參數是數據庫版本號,數據庫建立的時候默認版本號爲 1
,當咱們傳入的版本號和數據庫當前版本號不一致時 onupgradeneeded
就會被調用,固然咱們不能試圖打開比當前數據庫版本低的version
,不然調用的就是 onerror
了。this
onupgradeneeded
被調用時,咱們能夠作一些建表、索引等操做。spa
有了數據庫後咱們天然但願建立一個表用來存儲數據,但 indexedDB
中沒有表的概念,而是 objectStore
,一個數據庫中能夠包含多個 objectStore
,objectStore
是一個靈活的數據結構,能夠存放多種類型數據。code
咱們可使用每條記錄中的某個指定字段做爲鍵值(keyPath),也可使用自動生成的遞增數字做爲鍵值(keyGenerator),也能夠不指定。選擇鍵的類型不一樣,objectStore
能夠存儲的數據結構也有差別。對象
function closeDB(dbObj) { dbObj.db.close(); }
function deleteDB(dbObj) { indexedDB.deleteDatabase(dbObj.name); }
在對新數據庫作任何事情以前,須要開始一個事務。事務中須要指定該事務跨越哪些 object store
。blog
事務具備三種模式
read
,不能修改數據庫數據,能夠併發執行readwrite
,能夠進行讀寫操做版本變動:verionchange
function addData(dbObj, tableName, data, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var request = objectStore.add(data); request.onsuccess = function (e) { if (cb) { cb({ error: 0, data : data }) } }; request.onerror = function (e) { if (cb) { cb({ error: 1 }) } } }
function deleteData(dbObj, tableName, id, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var request = objectStore.delete(parseInt(id)); request.onsuccess = function (e) { if (cb) { cb({ error: 0, data : parseInt(id) }) } }; request.onerror = function (e) { if (cb) { cb({ error: 1 }) } } }
function getDataAll(dbObj, tableName, cb) { var transaction = dbObj.db.transaction(tableName, 'readonly'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var rowData = []; objectStore.openCursor(IDBKeyRange.lowerBound(0)).onsuccess = function (event) { var cursor = event.target.result; if (!cursor && cb) { cb({ error: 0, data : rowData }); return; } rowData.push(cursor.value); cursor.continue(); }; }
function getDataById(dbObj, tableName, id, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var request = objectStore.get(id); request.onsuccess = function (e) { if (cb) { cb({ error: 0, data : e.target.result }) } }; request.onerror = function (e) { if (cb) { cb({ error: 1 }) } } }
function getDataBySearch(dbObj, tableName, keywords, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var boundKeyRange = IDBKeyRange.only(keywords); var rowData; objectStore.index("nickName").openCursor(boundKeyRange).onsuccess = function (event) { var cursor = event.target.result; if (!cursor) { if (cb) { cb({ error: 0, data : rowData }) } return; } rowData = cursor.value; cursor.continue(); }; }
function getDataByPager(dbObj, tableName, start, end, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var boundKeyRange = IDBKeyRange.bound(start, end, false, true); var rowData = []; objectStore.openCursor(boundKeyRange).onsuccess = function (event) { var cursor = event.target.result; if (!cursor && cb) { cb({ error: 0, data : rowData }); return; } rowData.push(cursor.value); cursor.continue(); }; }
function updateData(dbObj, tableName, id, updateData, cb) { var transaction = dbObj.db.transaction(tableName, 'readwrite'); transaction.oncomplete = function () { console.log("transaction complete"); }; transaction.onerror = function (event) { console.dir(event) }; var objectStore = transaction.objectStore(tableName); var request = objectStore.get(id); request.onsuccess = function (e) { var thisDB = e.target.result; for (key in updateData) { thisDB[key] = updateData[key]; } objectStore.put(thisDB); if (cb) { cb({ error: 0, data : thisDB }) } }; request.onerror = function (e) { if (cb) { cb({ error: 1 }) } } }
ps: 實現細節部分待有時間進行補充完善~