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