indexedDB使用總結(jié)

前言

最近在做的項(xiàng)目上有離線功能谦屑,需要將大量的數(shù)據(jù)存儲(chǔ)在前端谤碳。結(jié)合項(xiàng)目實(shí)際需求最后決定使用indexedDB來進(jìn)行存儲(chǔ)材泄。以下是我對(duì)indexedDB的使用以及一些踩過的坑進(jìn)行總結(jié)悠鞍。

1.基本使用

1.1 打開/新建數(shù)據(jù)庫(kù)

使用indexedDB.open()方法

var request = window.indexedDB.open(databaseName, version);

databaseName:數(shù)據(jù)庫(kù)名稱染簇,如果指定數(shù)據(jù)庫(kù)不存在,則會(huì)新建該名稱的數(shù)據(jù)庫(kù)
version:整數(shù)参滴,表示數(shù)據(jù)庫(kù)的版本號(hào)。打開已有數(shù)據(jù)庫(kù)默認(rèn)為當(dāng)前版本锻弓。新建數(shù)據(jù)庫(kù)時(shí)砾赔,默認(rèn)版本號(hào)為1。

indexedDB.open()方法返回一個(gè) IDBRequest 對(duì)象青灼。這個(gè)對(duì)象通過以下三種事件處理打開數(shù)據(jù)庫(kù)的操作結(jié)果暴心。
(1)onerror:打開數(shù)據(jù)庫(kù)失敗

request.onerror = function (event) {
  console.log('數(shù)據(jù)庫(kù)打開報(bào)錯(cuò)');
};

(2)success:打開數(shù)據(jù)庫(kù)成功

var db;
request.onsuccess = function (event) {
  db = request.result;
  console.log('數(shù)據(jù)庫(kù)打開成功');
};

(3) upgradeneeded:數(shù)據(jù)庫(kù)版本升級(jí)或創(chuàng)建數(shù)據(jù)庫(kù)時(shí)觸發(fā),在該事件中創(chuàng)建數(shù)據(jù)表

var db;
request.onupgradeneeded = function (event) {
  db = event.target.result;
  if (!db.objecttables.contains('table')) { //判斷數(shù)據(jù)庫(kù)中是否已經(jīng)存在該名稱的數(shù)據(jù)表
    objectStore = db.createObjectStore('table', { keyPath: 'id' }); 
    objectStore.createIndex('name', 'name', { unique: false }); 
    objectStore.createIndex('age', 'age', { unique: true }); 
  }
}

db.createObjectStore('table', { keyPath: 'id' })表示新建名稱為table的表,主鍵為id杂拨,主鍵(key)是默認(rèn)建立索引的屬性专普。后面會(huì)介紹詳細(xì)用法
如果數(shù)據(jù)記錄里面沒有合適作為主鍵的屬性,那么可以讓 IndexedDB 自動(dòng)生成主鍵弹沽。

var objectStore = db.createObjectStore('table',{ autoIncrement: true });

objectStore.createIndex('name', 'name', { unique: false })表示建立索引檀夹,可根據(jù)索引查詢指定條件的數(shù)據(jù),可建立多條索引策橘;三個(gè)參數(shù)分別表示為 索引名稱炸渡,索引所在的屬性,該屬性是否包含相同的值

1.2 新增/更新數(shù)據(jù)

function changeData() {
  var request = db.transaction(['table'], 'readwrite') //readwrite表示有讀寫權(quán)限
    .objectStore('table')
    .add({ id: 1, name: 'leiyin', age: 24}); //新增數(shù)據(jù)
    或
    .put({ id: 1, name: 'leiyin', age: 24}); //更新數(shù)據(jù)
  request.onsuccess = function (event) {
    console.log('數(shù)據(jù)寫入成功');
  };
  request.onerror = function (event) {
    console.log('數(shù)據(jù)寫入失敗');
  }
}
changeData();

PS:indexedDB都是異步操作丽已,具體操作可在回調(diào)函數(shù)中寫

1.3 讀取數(shù)據(jù)

(1)根據(jù)主鍵讀取數(shù)據(jù)
objectStore.get()方法用于讀取數(shù)據(jù)蚌堵,參數(shù)是主鍵的值。

function read() {
   var transaction = db.transaction(['table']);
   var objectStore = transaction.objectStore('table');
   var request = objectStore.get(1);
   request.onerror = function(event) {
     console.log('事務(wù)失敗');
   };
   request.onsuccess = function( event) {
      if (request.result) {
        console.log(request.result);
      } else {
        console.log('未獲得數(shù)據(jù)記錄');
      }
   };
}
read();

(2) 通過索引讀取數(shù)據(jù)
使用索引能自定義字段進(jìn)行搜索促脉,如果不建立索引則只能通過主鍵搜索辰斋。

var transaction = db.transaction(['table'], 'readonly');
var store = transaction.objectStore('table');
var index = store.index('name');
var request = index.get('leiyin');
request.onsuccess = function (e) {
  var result = e.target.result;
  if (result) {
    // ...
  } else {
    // ...
  }
}

(3) 通過游標(biāo)和索引讀取數(shù)據(jù)
上述只能讀取到匹配條件的第一條數(shù)據(jù)記錄策州,假如要獲取多條滿足條件的數(shù)據(jù)記錄,則要使用游標(biāo)宫仗。
游標(biāo)與索引結(jié)合能將通過游標(biāo)將所有滿足所有條件的數(shù)據(jù)全部拿到够挂。

var store = db.transaction('table','readwrite').objectStore('table');
var index = store.index('name');
var request=index.openCursor(IDBKeyRange.only('leiyin'))
request.onerror = function(e){
}
request.onsuccess = function(e){
    console.log('游標(biāo)開始查詢')
    var cursor = e.target.result;
    if(cursor){//必須要檢查
        console.log(cursor);
        cursor.continue();//遍歷了存儲(chǔ)對(duì)象中的所有內(nèi)容
    }else{
        //...
    }
};

1.4 刪除數(shù)據(jù)

(1)根據(jù)主鍵刪除數(shù)據(jù)

function remove() {
  var request = db.transaction(['table'], 'readwrite')
    .objectStore('table')
    .delete(1);
  request.onsuccess = function (event) {
    console.log('數(shù)據(jù)刪除成功');
  };
}
remove();

(2) 通過游標(biāo)和索引刪除數(shù)據(jù)

function cursorDeldteData(db,table){
    //通過游標(biāo)刪除記錄
    var store = db.transaction(table,'readwrite').objectStore(table);
    var request = store.openCursor();
    request.onsuccess = function(e){
        var cursor = e.target.result,
            value,
            deleteRequest;
        if(cursor){
          deleteRequest = cursor.delete();//請(qǐng)求刪除當(dāng)前項(xiàng)
          deleteRequest.onerror = function(){
            console.log('游標(biāo)刪除該記錄失敗');
          };
          cursor.continue();
        }
    };
}

1.5 清除數(shù)據(jù)表中的數(shù)據(jù)

由于刪除數(shù)據(jù)庫(kù)后不能重新創(chuàng)建相同名稱的數(shù)據(jù)庫(kù),而項(xiàng)目又需要對(duì)相同名稱的數(shù)據(jù)庫(kù)進(jìn)行操作藕夫,我選擇了清除數(shù)據(jù)庫(kù)中的所有表內(nèi)的數(shù)據(jù)孽糖。

function clear(db,table){
    //刪除存儲(chǔ)空間全部記錄
    var store = db.transaction(table,'readwrite').objectStore(table);
    store.clear();
    console.log('已刪除存儲(chǔ)空間'+table+'全部記錄');
}
clear();

1.6 刪除數(shù)據(jù)庫(kù)

indexedDB.deleteDatabase(DatabaseName); 

經(jīng)測(cè)試發(fā)現(xiàn),刪除數(shù)據(jù)庫(kù)成功后毅贮,不能再創(chuàng)建相同名稱的數(shù)據(jù)庫(kù)办悟。

2.碰到的問題

2.1 IOS兼容性問題

問題描述:
兼容性問題,indexedDB中使用索引與游標(biāo)結(jié)合可刪除滿足條件的多條數(shù)據(jù)滩褥,在Android中可刪除多條病蛉,但在iOS中只能刪除一條滿足條件的數(shù)據(jù)
問題分析
經(jīng)反復(fù)測(cè)試,發(fā)現(xiàn)iOS中cursor.continue()方法失效瑰煎,該方法作用是繼續(xù)向下匹配铺然。
問題解決
1.使用遞歸方法實(shí)現(xiàn)功能。
2.但是測(cè)試后發(fā)現(xiàn)cursor.continue()方法刪除數(shù)據(jù)要更快一些酒甸。
3為了提高性能魄健,.判斷當(dāng)前設(shè)備是iOS還是Android,假如為iOS使用遞歸插勤,為Android使用cursor.continue()沽瘦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市农尖,隨后出現(xiàn)的幾起案子析恋,更是在濱河造成了極大的恐慌,老刑警劉巖卤橄,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绿满,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窟扑,警方通過查閱死者的電腦和手機(jī)喇颁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嚎货,“玉大人橘霎,你說我怎么就攤上這事≈呈簦” “怎么了姐叁?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我外潜,道長(zhǎng)原环,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任处窥,我火速辦了婚禮嘱吗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滔驾。我一直安慰自己谒麦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布哆致。 她就那樣靜靜地躺著绕德,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摊阀。 梳的紋絲不亂的頭發(fā)上耻蛇,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音驹溃,去河邊找鬼城丧。 笑死延曙,一個(gè)胖子當(dāng)著我的面吹牛豌鹤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枝缔,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼布疙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了愿卸?” 一聲冷哼從身側(cè)響起灵临,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趴荸,沒想到半個(gè)月后儒溉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡发钝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年顿涣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酝豪。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涛碑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出孵淘,到底是詐尸還是另有隱情蒲障,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站揉阎,受9級(jí)特大地震影響庄撮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毙籽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一重窟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惧财,春花似錦巡扇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至搀突,卻和暖如春刀闷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仰迁。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工甸昏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徐许。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓施蜜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親雌隅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子翻默,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354