html5 indexeddb,关于使用HTML5提供的indexedDB的一下心得
一:什么是indexedDB?
indexedDB是HTML5實現本地存儲一個小型數據庫,并且在Chome,IE等主流瀏覽器已經得到很好的支持,
IndexedDB是為了能夠在客戶端存儲大量的結構化數據,并且使用索引高效檢索的API。但是這些API的使用很糾結,就是大多數的API全是異步執行。它存儲的數據格式是json對象格式,由鍵值對表示,像這樣:
具體操作:f12,找resorce,找indexedDB
二:我使用indexedDB的問題
使用indexedDB的時候會出現很多比較糾結的情況,因為它的很多基本操作都是異步執行的,官方文檔說提供的有同步的API,但是直到最后也沒有找到,再加上js這種弱類型的語言,剛接觸的時候是在讓我苦不堪言。特在此總結下我在使用indexedDB時遇到的問題和最終的解決方案,希望有用。
三:基本使用
1,建立數據庫:
var myDB={
dbName="testDB",
db=null
}
var request=window.indexedDB.open(myDB.dbName);
解釋:這個語句表示打開一個名叫testDB的數據庫,如果該數據庫不存在,會自動創建一個名為textDB的數據庫。這個requese提供三個回調函數,分別是onsuccess(),onerror(),onupgrandeneed(). 這三個函數分別在打開或者創建數據庫成功,失敗,更新時候調用。
requese.onsuccess=function(e){
console.log("打開數據庫成功,db==="+e.target.result);
myDB.db=e.target.result;
}
這個地方的e.target.result就是已經打開的數據庫對象db,接下來的任何操作都要用到這個db,所以最好把這個代碼封裝成一個函數,用回調函數的方法,直接返回一個db,以便于后來操作。 同理,onerror方法就是在打開數據庫失敗的時候調用,可以在onerror函數里打印錯誤信息,例如:
request.οnerrοr=function(e){
console.log("打開數據庫失敗,錯誤信息為:"+e.terget.error.message);
}
重要的說一下第三個函數,onupgrandeneed(),這個函數在數據庫需要更新的時候調用,比如,第一次創建數據庫的時候或者是數據庫新添加了objectStore時,(objectStore相當于表的概念)。例如:
request.onupgrandeneed=function(e){
var objectStore=myDB.db.createObjectStore("objectStore1",{keyPath:"ID"});
var objectStore2=myDB.db.createObjectStore2("objectStore2",{keyPath:"ID"});
//給objectStore2表加一個索引
objectStore2.creatIndex("timeIndex","Time",{unique:false});
}
解釋一下:creatObjectStore()函數,用于建一個objectStore,而objectStore的概念相當于在其他數據庫中的表的概念。該函數的兩個參數分別為(表名稱,主鍵)。
這里說主鍵并不準確,但是跟主鍵的概念很像,請原諒我的簡單粗暴。 在這里值得注意的就是:存進去的數據,必須有這個keyPath的鍵,否則會報錯,而其他的無所謂,可有可無,看你的需求。如果你要使用索引的話,那么這個索引值得字段也必須有的。
creatIndex()函數的三個參數分別是(索引名稱,以哪個字段做索引,是否唯一)
2,使用回調函數獲取db對象
var myDB={
dbName="testDB",
db=null
}
openDB:function(callBack){
var request=window.indexedDB.open(myDB.dbName);
requese.onsuccess=function(e){
console.log("打開數據庫成功,db==="+e.target.result);
myDB.db=e.target.result;
callBack( myDB.db);
}
}
這里的callBack是一個函數,當調用openDB方法的時候,需要傳進來一個函數作為參數。在onsuccess()函數里,調用callBack,把獲得到的db對象傳給調用openDB的對象。具體使用下邊有。
解釋一下用這種辦法獲取db的原因: 因為onsuccess的調用是在打開數據庫成功之后,而這個函數是異步調用的,也就是說,你不知道什么時候db是存在的,如果直接return db,得到的會是undefined。而使用js的回調,會很巧妙的避免這個問題。
3,增加一條記錄
openDB(function(db){
var transaction=db.transaction("objectStore1","readwrite");
var objectStore=transaction.objectStore("objectStore2");
var value={"ID":001,"Time":2013.01.02};
var request=objectStore.put(value);
//這個地方也可以用add,跟put的區別是add不會覆蓋如果已經存在的數據,而put會覆蓋。
request.onsuccess=function(e){
console.log("插入成功");
}
transaction.oncomplete=function(){
console.log("這個時候才是真的插入成功了");
}
});
這個地方有幾個微妙的地方
1,定義的value必須有你建立objectStore的時候定義的keyPath和索引值
2,transaction.oncomplete字面意思是事務提交,顧名思義,就是在定義的這個事務全部執行完成的時候,才會執行的。只有在這個函數執行之后,再去表里查詢這條數據,才會有,否則會查不到,哪怕是在onsuccess執行之后馬上查詢,也是查詢不到的。當初為這個問題糾結很久,這跟傳統的關系型數據庫相差較大。
3,關于事務的定義,如果需要批量插入數據,事務的定義要定義在循環之外,否則會很大程度的影響插入效率。例如
4,要注意transaction的權限問題,readonly代表只讀,readwrite代表讀寫。 默認是readonly
openDB(function(db){
var transaction=db.transaction("objectStore1","readwrite");
var objectStore=transaction.objectStore("objectStore2");
for(var i=0;i<1000;i++){
var value={"ID":i,"Time":2013.01.02};
var request=objectStore.put(value);
//這個地方也可以用add,跟put的區別是add不會覆蓋如果已經存在的數據,而put會覆蓋。
request.onsuccess=function(e){
console.log("插入成功");
}
}
transaction.oncomplete=function(){
console.log("這個時候才是真的插入成功了");
}
});
像這樣,把transaction定義在for循環外邊,1000條數據會秒插入。當初為了省事,把插入直接封裝成一個函數,在這個函數里定義事務,會很慢,十幾秒才把1000條數據插入完,慢的我懷疑人生。后來改成把transaction也傳進來,但是這會導致transaction失效。會報:this transaction is not activited。
4,刪除一條記錄
openDB(function(db){
var transaction=db.transaction("objectStore2",'readwrite');
var store=transaction.objectStore("objectStore2");
store.delete(key);
}
});
//簡單粗暴,不多解釋
###5,修改一條記錄
openDB(function(db){
var transaction=db.transaction("objectStore2",'readwrite');
var store=transaction.objectStore("objectStore2");
var request=store.get(key);
request.onsuccess=function(e){
var model=e.target.result;
model.Time=2015.09.09;
store.put(model);
};
}
});
//查出來,修改,再放進去覆蓋掉。
###5,查詢一條記錄
按keyPath查詢
openDB(function(db){
var transaction=db.transaction("objectStore2",'readonly');
var store=transaction.objectStore("objectStore2");
var request=store.get(key);
request.onsuccess=function(e){
var model=e.target.result;
//這個地方最好也用回調函數把查到的值返回回去。方法同openDB()
};
}
});
游標查詢全部
openDB(function(db){
var transaction=db.transaction("objectStore2",'readonly');
var array=new Array();
var store=transaction.objectStore("objectStore2");
var request=store.openCursor();
request.onsuccess=function(){
var cursor=e.target.result;
if(cursor){
array.push(cursor.value);
cursor.continue();
}else{
// callBack(array);
//在這里可以把數組返回回去。同openDB()
//也可以在transaction的oncomplete()中把數組返回回去。
}
}
}
});
未完待補充
總結
以上是生活随笔為你收集整理的html5 indexeddb,关于使用HTML5提供的indexedDB的一下心得的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: phpstrom函数注释模板_PHPST
- 下一篇: --------溢出植入型木马(后门)的