1. 程式人生 > >HTML5基礎(indexedDB)

HTML5基礎(indexedDB)

概述

IndexedDB是HTML5規範裡新出現的瀏覽器裡內建的資料庫。
對於在瀏覽器裡儲存資料,你可以使用cookies或local storage,但它們都是比較簡單的技術,而IndexedDB提供了類似資料庫風格的資料儲存和使用方式。
儲存在IndexedDB裡的資料是永久儲存,不像cookies那樣只是臨時的。
IndexedDB裡提供了查詢資料的功能,在online和offline模式下都能使用。
你可以用IndexedDB儲存大型資料。

IndexedDB裡資料以物件的形式儲存,每個物件都有一個key值索引。
IndexedDB裡的操作都是事務性的。
一種物件儲存在一個objectStore裡,objectStore就相當於關係資料庫裡的表。
IndexedDB可以有很多objectStore,objectStore裡可以有很多物件。每個物件可以用key值獲取。

IndexedDB vs LocalStorage

IndexedDB和LocalStorage都是用來在瀏覽器裡儲存資料,但它們使用不同的技術,有不同的用途,你需要根據自己的情況適當的選擇使用哪種。
LocalStorage是用key-value鍵值模式儲存資料,但跟IndexedDB不一樣的是,它的資料並不是按物件形式儲存。它儲存的資料都是字串形式。
如果你想讓LocalStorage儲存物件,你需要藉助JSON.stringify()能將物件變成字串形式,再用JSON.parse()將字串還原成物件。
但如果要儲存大量的複雜的資料,這並不是一種很好的方案。
畢竟,localstorage就是專門為小數量資料設計的,它的api是同步的。

IndexedDB很適合儲存大量資料,它的API是非同步呼叫的。
IndexedDB使用索引儲存資料,各種資料庫操作放在事務中執行。
IndexedDB甚至還支援簡單的資料型別。
IndexedDB比localstorage強大得多,但它的API也相對複雜。

對於簡單的資料,你應該繼續使用localstorage,但當你希望儲存大量資料時,IndexedDB會明顯的更適合,IndexedDB能提供你更為複雜的查詢資料的方式。

IndexedDB vs Web SQL

WebSQL也是一種在瀏覽器裡儲存資料的技術,跟IndexedDB不同的是,IndexedDB更像是一個NoSQL資料庫,而WebSQL更像是關係型資料庫,使用SQL查詢資料。
W3C已經不再支援這種技術。
因為不再支援,所以你就不要在專案中使用這種技術了。

IndexedDB vs Cookies

Cookies(小甜點)聽起來很好吃,但實際上並不是。
每次HTTP接受和傳送都會傳遞Cookies資料,它會佔用額外的流量。
例如,如果你有一個10KB的Cookies資料,傳送10次請求,那麼,總計就會有100KB的資料在網路上傳輸。
Cookies只能是字串。
瀏覽器裡儲存Cookies的空間有限,很多使用者禁止瀏覽器使用Cookies。
所以,Cookies只能用來儲存小量的非關鍵的資料。

IndexedDB的用法

想要理解IndexedDB,最好的方法是建立一個簡單的web應用:把你們班的學生的學號和姓名儲存在IndexedDB裡。IndexedDB裡提供了簡單的增、刪、改、查介面。

開啟一個IndexedDB資料庫

首先,你需要知道你的瀏覽器是否支援IndexedDB。請使用最新版的谷歌瀏覽器或火狐瀏覽器。低版本的IE是不行的。

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

if(!window.indexedDB)
{
    console.log("你的瀏覽器不支援IndexedDB");
}

一旦你的瀏覽器支援IndexedDB,我們就可以開啟它。

你不能直接開啟IndexedDB資料庫。IndexedDB需要你建立一個請求來開啟它。

 var request = window.indexedDB.open("testDB", 2);

第一個引數是資料庫的名稱,第二個引數是資料庫的版本號。版本號可以在升級資料庫時用來調整資料庫結構和資料。

但你增加資料庫版本號時,會觸發onupgradeneeded事件,這時可能會出現成功、失敗和阻止事件三種情況。

var db;
request.onerror = function(event){
    console.log("開啟DB失敗", event);
}
request.onupgradeneeded   = function(event){
    console.log("Upgrading");
    db = event.target.result;
    var objectStore = db.createObjectStore("students", { keyPath : "rollNo" });
};
request.onsuccess  = function(event){
    console.log("成功開啟DB");
    db = event.target.result;
}

onupgradeneeded事件在第一次開啟頁面初始化資料庫時會被呼叫,或在當有版本號變化時。
所以,你應該在onupgradeneeded函式裡建立你的儲存資料。
如果沒有版本號變化,而且頁面之前被開啟過,你會獲得一個onsuccess事件。
如果有錯誤發生時則觸發onerror事件。
如果你之前沒有關閉連線,則會觸發onblocked事件。

在上面的程式碼片段裡,我們建立了一個Object Store,叫做“students”,用“rollNo”做資料鍵名。

往ObjectStore裡新增物件

為了往資料庫裡新增資料,我們首先需要建立一個事務,並要求具有讀寫許可權。
在indexedDB裡任何的存取物件的操作都需要放在事務裡執行。

var transaction = db.transaction(["students"],"readwrite");
transaction.oncomplete = function(event) {
    console.log("Success");
};

transaction.onerror = function(event) {
    console.log("Error");
};  
var objectStore = transaction.objectStore("students");

objectStore.add({rollNo: rollNo, name: name});

從ObjectStore裡刪除物件

刪除跟新增一樣,需要建立事務,然後呼叫刪除介面,通過key刪除物件。

db.transaction(["students"],"readwrite").objectStore("students").delete(rollNo);

我把語句合併到了一起,變得更簡單,但效果是一樣的。

通過key取出物件

往get()方法裡傳入物件的key值,取出相應的物件。

var request = db.transaction(["students"],"readwrite").objectStore("students").get(rollNo);
request.onsuccess = function(event){
    console.log("Name : "+request.result.name);    
};

更新一個物件

為了更新一個物件,首先要把它取出來,修改,然後再放回去。

var transaction = db.transaction(["students"],"readwrite");
var objectStore = transaction.objectStore("students");
var request = objectStore.get(rollNo);
request.onsuccess = function(event){
    console.log("Updating : "+request.result.name + " to " + name);
    request.result.name = name;
    objectStore.put(request.result);
};