HTML5 InexedDB API 簡介

本文將介紹如何利用 HTML5 InexedDB API 來建立 IndexedDB 並寫入資料。

致謝

感謝點部落團隊舉辦 HTML 5 & JavaScript 程式開發實戰贈書活動,讓筆者有幸可以獲得這本好書。

摘要

在前面筆者跟大家介紹 HTML5 Web Storage 可以用來儲存 HTML 應用程式所需的資料,他是使用 Key / Value 的結構來存放資料在 Client 端,若您需要更複雜的資料儲存功能,或許本文接下來要介紹的 IndexedDB 會更符合您的需求。IndexedDB 可視為一個特殊結構的離線 DBMS,儲存的位置是在 Client 端,但概念上與過去您使用的 SQL Server 等 DBMS 有異曲同工之妙,以下將介紹如何建立 HTML5 IndexedDB 以及如何對它做 CRUD。

【建立 IndexedDB

由於建立 IndexedDB 的連線需要遵循 IDBFactory 介面的定義,而每個瀏覽器實作 IDBFactory 的方式又不太一樣,因此您可以用通用的寫法來實作之,例如下列程式碼的第 8 列。接著當使用者按下建立  IndexedDB 時,透過 CreateDB  方法來連接名稱為 MyFirstIDB 的資料庫,若該資料庫存在則會與之建立連線,反之則會先建立它再連線,此時並還不能開始使用 IndexedDB,您必須在 onsusscess 事件屬性中取得 IndexedDB 的實體後才能對它進行操作。

若想要刪除 IndexedDB 只要呼叫 indexedDB.deleteDatabase 方法即可,如第 42 列。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>HTML5 IndexedDB API Demo</title>
    <script type="text/javascript">
        //針對不同瀏覽器實作 IDBFactory 的方式不同 的共通寫法
        var idbf = window.indexedDB || window.mozIndexedDB || window.msIndexedDB;

        //建立資料庫
        function CreateDB()
        {
            //連接並開啟 MyFirstIDB,如果不存在就先建立之。
            var idb = idbf.open("MyFirstIDB");

            //連接失敗時的錯誤處理
            idb.onerror = function (e) {
                document.getElementById("divResult").innerHTML += e.target.error + "<br/>";
            }

            //開啟成功後取得 IndexedDB 的實體
            idb.onsuccess = function (e) {
                idb = e.target.result;
                document.getElementById("divResult").innerHTML += "MyFirstIDB 建立完成"
                    + " - 狀態:" + this.readyState
                    + " - 目前版本:" + idb.version
                    + "<br/>";
            }

            //版本異動時觸發
            idb.onupgradeneeded = function (e) {
                document.getElementById("divResult").innerHTML += "版本異動"
                    + " - 舊版本:" + e.oldVersion
                    + " - 新版本:" + e.newVersion
                    + " - 目前版本:" + idb.version
                    + "<br/>";
            }
        }

        //刪除資料庫
        function DeleteDB() {
            idbf.deleteDatabase("MyFirstIDB");
        }
    </script>
</head>
<body>
    <input type="button" value="建立 IndexedDB" onclick="CreateDB()" />
    <input type="button" value="刪除 IndexedDB" onclick="DeleteDB()" />
    <br />
    <div id="divResult" />
</body>
</html>

每一個 IndexedDB 都會有自己的版本編號,版本編號的異動會觸發 onupgradeneeded 事件,您可以在這個事件中做有關 ObjectStore 的操作或異動,什麼是 ObjectStore?請見下一節。

您會發現當按下建立 IndexedDB 時,因為是第一次建立觸發資料庫版本由 0 變成 1,版本升級的緣故造成 onupgradeneeded 事件屬性會先被執行,接著資料庫連接成功時才會觸發 onsuccess,因此產生下圖的結果,從 Google Chrome 開發人員工具您也可以看到 MyFirstIDB 的確被建立起來。

SNAGHTMLb1bf6b

建立 ObjectStore

上一節提到如何建立 IndexedDB,您可以想像它是您在使用 SQL Server 時的使用者資料庫,有了資料庫後需要建立資料表才能儲存應用程式所需的資料,在 IndexedDB 中並沒有資料表,取而代之的是 ObjectStore,因此您可以利用 IndexedDB 的 createObjectStore 方法來建立 ObjectStore,建立時需要指定其名稱,接著您可以再利用 ObjectStore 的 createIndex 方法來建立相當於一般 DBMS 中的資料行,您也可以設定該 Index 是否要自動加號或是是否可重複等等的限制條件。


idb.onupgradeneeded = function (e) {
	idb = e.currentTarget.result;
	var os = idb.createObjectStore("UserGroup", { keyPath: "id", autoIncrement: true });
	os.createIndex("name", "Name", { unique: true });
	os.createIndex("leader", "Leader", { unique: false });

	document.getElementById("divResult").innerHTML += "版本異動"
		+ " - 舊版本:" + e.oldVersion
		+ " - 新版本:" + e.newVersion
		+ " - 目前版本:" + idb.version
		+ "<br/>";
}

新增資料

有了 ObjectStore 後您可以開始建立資料,您可以利用 ObjectStore 的 add 方法來建立資料,其中每一筆資料稱之為一筆 Record。例如下列的程式碼,您必須指定要 Record 的內容(value)和名稱(key)。除了一筆一筆輸入外,您也可以將 JSON 格式的資料以迴圈方式來新增到 ObjectStore。


var ug = [
	{ Name: "Study4", Leader: "Sky" },
	{ Name: "twMVC", Leader: "Demo" },
	{ Name: "SQL PASS", Leader: "Byron" },
		];
for (i in ug) {
	os.add(ug[i]);
}

從下圖可以看出經過上面的程式碼,三筆 JSON 中的資料確實已經儲存到 ObjectStore。

SNAGHTML1ce92a7

SNAGHTML1cec9dc

SNAGHTML1cf60be

參考資料

- HTML5 & JavaScript 程式開發實戰 - 導讀

- Windows Store Apps: Using IndexedDB for Storing Data using HTML5 and JavaScript

- HTML5 Indexed Database API 入門(序)

- Indexed Database API

- Indexed database (Windows Store apps)

- Indexed Database API

- IndexedDB

- Using the HTML5 IndexedDB API

- Indexed Database API W3C Draft Implementation

- Getting Started with IndexedDB