IndexedDB的JS接口設(shè)計詳解
接下來介紹IndexedDB(以下簡稱IDB)的JS接口設(shè)計

如圖所示,我們按照操作過程,把IDB的接口分成三部分來介紹:
1.初始化數(shù)據(jù)庫連接
2.在數(shù)據(jù)庫中建表
3.在表中存取數(shù)據(jù)
初始化數(shù)據(jù)庫連接
- var req = window.IndexedDB.open(dbName, dbVersion);
- req.onsuccess = function (e) {...}
- req.onupgradeneeded = function (e) {...}
- req.onerror = function (e) {...}
這里有兩個重要的參數(shù),dbName是數(shù)據(jù)庫的名稱,dbVersion是數(shù)據(jù)庫的“版本”。第2個參數(shù)“版本”可能不太好理解,IDB不允許數(shù)據(jù)庫中的表在同一個版本中發(fā)生變化,所以當我們創(chuàng)建新表或刪除舊表的時候,必須使用一個不一樣的版本號。他的作用在于避免重復修改數(shù)據(jù)庫的表結(jié)構(gòu)。默認的版本是空字符串"",我們在使用時,可以使用"1.0"。如果請求中的版本號和當前數(shù)據(jù)庫的版本號相同,則會觸發(fā)onsuccess事件,如果版本號不同,則會觸發(fā)onupgradeneeded事件,我們在這一事件中可以對數(shù)據(jù)庫的表結(jié)構(gòu)進行修改,然后再觸發(fā)onsuccess事件。
在數(shù)據(jù)庫中建表
- req.onupgradeneeded = function (e) {
- var db = req.result;
- vardb.createObjectStore(storeName, optionParameters);
- };
之前提到了,當被訪問的數(shù)據(jù)庫版本號需要發(fā)生改變時,onupgradeneeded事件會被觸發(fā),我們就從這個事件繼續(xù)說起。通過req.result我們可以得到當前的數(shù)據(jù)庫對象db。db有一個方法createObjectStore,是專門用來創(chuàng)建表的。***個參數(shù)是表的名稱,第二個參數(shù)是可選的,它決定了我們要創(chuàng)建的表是內(nèi)聯(lián)關(guān)鍵字還是外部關(guān)鍵字,關(guān)鍵字是否需要自動生成,代表這兩個設(shè)置的字段分別是keyPath和autoIncrement。比如,當?shù)诙€參數(shù)是
- {keyPath: 'profile.id', autoIncrement: false}
時,說明這個表采用內(nèi)聯(lián)關(guān)鍵字,且keyPath是profile.id,同時關(guān)鍵字不是自增的,需要每次插入數(shù)據(jù)時手動設(shè)定;當?shù)诙€參數(shù)是
- {autoIncrement: true}
時,說明這個表采用外部關(guān)鍵字,并且關(guān)鍵字是自增的。
同樣的,我們可以在onupgradeneeded事件中刪除一個表,方法是db.deleteObjectStore(storeName)。道理很簡單,就不展開論述了。
在表中存取數(shù)據(jù)
- req.onsuccess = function (e) {
- var db = req.result;
- var transaction = db.transaction(storeNames, mode);
- var store = transaction.objectStore(storeName);
- var subReq = store.add(value, key);
- // var subReq = store.get(key);
- // var subReq = store.delete(key);
- // var subReq = store.clear();
- subReq.onsuccess = function (e) {
- console.log(subReq.result);
- };
- };
對表中數(shù)據(jù)的存取通常是在onsuccess事件之后進行的。同樣的,我們可以通過req.result獲取數(shù)據(jù)庫對象db,并隨時通過db進行各種存取數(shù)據(jù)的操作。
上一篇文章提到了,所有的數(shù)據(jù)庫操作都是在事務(transaction)中進行的,具體代碼格式是這樣的:
***句,先創(chuàng)建一個transaction,兩個參數(shù)分別是會涉及到的表的名字和讀寫模式,表的名字可以是數(shù)據(jù)也可以是字符串,如"users"或["users", "articles"],讀寫模式可以是IDBTransaction.READ_ONLY或IDBTransaction.READ_WRITE。
第二句,用transaction對象獲取一個表,需要傳入的參數(shù)是表的名稱。
第三句及其后面的四句注釋掉的代碼,分別是我們可以利用store這個對象進行的基本的表操作——添加數(shù)據(jù)、獲取數(shù)據(jù)、刪除數(shù)據(jù)、清空表。參數(shù)也都很好理解,有一個要注意的地方是,添加數(shù)據(jù)時,key是可選項,如果我們已經(jīng)在表里定義了keyPath或表本身有自增關(guān)鍵字,則key是不需要寫的。
***,如***篇文章所說,這些操作是異步進行的,想獲得操作的結(jié)果,可以在subReq.onsuccess事件中,通過訪問subReq.result獲取操作結(jié)果。添加操作的操作結(jié)果是關(guān)鍵字,獲取數(shù)據(jù)的操作結(jié)果是對象的值,刪除操作和清空操作無需返回結(jié)果。
上述介紹是IDB的一些基本操作,我刻意省略掉了IDB中的遍歷、索引以及對各種出錯異常的處理。為的是給大家一個直觀的印象,用了上面的接口,我們起碼可以做到一件事,就是想使用localStorage一樣通過鍵值對來存取json對象。
下一篇文章,會進一步介紹遍歷操作,并結(jié)合firefox 10對IndexedDB的支持情況做一個簡單的demo。
【系列文章】
原文:http://bulaoge.net/topic.blg?dmn=g3g4&tid=2330716#Content