在HTML5本地儲存-Web SQL Database提到Web SQL Database其實已經被廢棄,而HTML5的支援的本機儲存其實變成了
Web Storage (Local Storage和Session Storage)與IndexedDB。 Web Storage使用簡單字串鍵值對在本地存儲數據,方便靈活,但是對於大量結構化數據存儲力不從心,IndexedDB是為了能夠在客戶端存儲大量的結構化數據,並且使用索引高效檢索的API。
在IndexedDB大部分操作並不是我們常用的呼叫方法,回傳結果的模式,而是請求-回應的模式,例如開啟資料庫的動作
var request=window.indexedDB.open('testDB');
這條指令並不會回傳一個DB物件的句柄,我們得到的是一個IDBOpenDBRequest對象,而我們希望得到的DB對像在其result屬性中,
這條指令請求的回應是一個IDBDatabase對象,這就是IndexedDB對象,
## 除了result,IDBOpenDBRequest接口定義了幾個重要屬性function openDB (name) { var request=window.indexedDB.open(name); request.onerror=function(e){ console.log('OPen Error!'); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; } var myDB={ name:'test', version:1, db:null }; openDB(myDB.name);程式碼中定義了一個myDB對象,在創建indexedDB request的成功毀掉函數中,把request取得的DB對象賦值給了myDB的db屬性,這樣就可以使用myDB .db來存取已建立的indexedDB了。 version我們注意到除了onerror和onsuccess,IDBOpenDBRequest還有一個類似回呼函數句柄-onupgradeneeded。這個句柄在我們請求開啟的資料庫的版本號碼和已經存在的資料庫版本號不一致的時候呼叫。 indexedDB.open()方法還有第二個可選參數,資料庫版本號,資料庫建立的時候預設版本號為1,當我們傳入的版本號和資料庫目前版本號不一致的時候onupgradeneeded就會被調用,當然我們不能試圖打開比當前資料庫版本低的version,否則調用的就是onerror了,修改一下剛才例子
function openDB (name,version) { var version=version || 1; var request=window.indexedDB.open(name,version); request.onerror=function(e){ console.log(e.currentTarget.error.message); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; request.onupgradeneeded=function(e){ console.log('DB version changed to '+version); }; } var myDB={ name:'test', version:3, db:null }; openDB(myDB.name,myDB.version);由於剛才已經創建了版本為1的數據庫,打開版本為3的時候,會在控制台輸出:DB version changed to 3關閉與刪除資料庫關閉資料庫可以直接呼叫資料庫物件的close方法
function closeDB(db){ db.close(); }刪除資料庫使用indexedDB物件的deleteDatabase方法
function deleteDB(name){ indexedDB.deleteDatabase(name); }簡單呼叫
var myDB={ name:'test', version:3, db:null }; openDB(myDB.name,myDB.version); setTimeout(function(){ closeDB(myDB.db); deleteDB(myDB.name); },500);由於非同步API願意,不能保證能夠在closeDB方法呼叫前取得db物件(實際上取得db物件也比執行一條語句慢很多),所以用了setTimeout延遲了一下。當然我們注意到每個indexedDB實例都有onclose回呼函數句柄,用以資料庫關閉的時候處理,有興趣同學可以試試,原理很簡單,不示範了。
键类型 | 存储数据 |
不使用 | 任意值,但是没添加一条数据的时候需要指定键参数 |
keyPath | Javascript对象,对象必须有一属性作为键值 |
keyGenerator | 任意值 |
都使用 | Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性 |
在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些object store。
事务具有三种模式
只读:read,不能修改数据库数据,可以并发执行
读写:readwrite,可以进行读写操作
版本变更:verionchange
var transaction=db.transaction([students','taecher']); //打开一个事务,使用students 和teacher object store var objectStore=transaction.objectStore('students'); //获取students object store
调用数据库实例的createObjectStore方法可以创建object store,方法有两个参数:store name和键类型。调用store的add方法添加数据。有了上面知识,我们可以向object store内添加数据了
keyPath
因为对新数据的操作都需要在transaction中进行,而transaction又要求指定object store,所以我们只能在创建数据库的时候初始化object store以供后面使用,这正是onupgradeneeded的一个重要作用,修改一下之前代码
function openDB (name,version) { var version=version || 1; var request=window.indexedDB.open(name,version); request.onerror=function(e){ console.log(e.currentTarget.error.message); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; request.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains('students')){ db.createObjectStore('students',{keyPath:"id"}); } console.log('DB version changed to '+version); }; }
这样在创建数据库的时候我们就为其添加了一个名为students的object store,准备一些数据以供添加
var students=[{ id:1001, name:"Byron", age:24 },{ id:1002, name:"Frank", age:30 },{ id:1003, name:"Aaron", age:26 }];
function addData(db,storeName){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); for(var i=0;i<students.length;i++){ store.add(students[i]); } } openDB(myDB.name,myDB.version); setTimeout(function(){ addData(myDB.db,'students'); },1000);
这样我们就在students object store里添加了三条记录,以id为键,在chrome控制台看看效果
keyGenerate
function openDB (name,version) { var version=version || 1; var request=window.indexedDB.open(name,version); request.onerror=function(e){ console.log(e.currentTarget.error.message); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; request.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains('students')){ db.createObjectStore('students',{autoIncrement: true}); } console.log('DB version changed to '+version); }; }
剩下的两种方式有兴趣同学可以自己摸索一下了
可以调用object store的get方法通过键获取数据,以使用keyPath做键为例
function getDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); var request=store.get(value); request.onsuccess=function(e){ var student=e.target.result; console.log(student.name); }; }
可以调用object store的put方法更新数据,会自动替换键值相同的记录,达到更新目的,没有相同的则添加,以使用keyPath做键为例
function updateDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); var request=store.get(value); request.onsuccess=function(e){ var student=e.target.result; student.age=35; store.put(student); }; }
调用object store的delete方法根据键值删除记录
function deleteDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); store.delete(value); }
调用object store的clear方法可以清空object store
function clearObjectStore(db,storeName){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); store.clear(); }
调用数据库实例的deleteObjectStore方法可以删除一个object store,这个就得在onupgradeneeded里面调用了
if(db.objectStoreNames.contains('students')){ db.deleteObjectStore('students'); }
这就是关于indexedDB的基本使用方式,很多同学看了会觉得很鸡肋,和我们正常自己定义个对象使用没什么区别,也就是能保存在本地罢了,这是因为我们还没有介绍indexedDB之所以称为indexed的杀器——索引,这个才是让indexedDB大显神通的东西,下篇我们就来看看这个杀器。
以上是HTML5本機儲存-詳解IndexedDB的基本使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!