成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

IndexedDB簡介與入門

存儲 存儲軟件
在本地離線存儲的場景中,IndexedDB作為一個nosql的本地DB存儲一直發揮著重要的作用。在需要存儲大量數據時,IndexedDB能夠有效地滿足你的需求。下面,我將簡單介紹下IndexedDB的簡單使用方法和在我閱讀W3C規范文檔時看到的一些需要注意的細節。

[[171775]]

背景

在本地離線存儲的場景中,IndexedDB作為一個nosql的本地DB存儲一直發揮著重要的作用。在需要存儲大量數據時,IndexedDB能夠有效地滿足你的需求。下面,我將簡單介紹下IndexedDB的簡單使用方法和在我閱讀W3C規范文檔時看到的一些需要注意的細節。實例大部分參照MDN中的介紹實例,同時對整體邏輯和實例做了一些改動。

使用方法

打開數據庫

我們使用window.indexedDB.open(DBName)來打開數據庫。具體實例如下:

  1. const request = window.indexedDB.open(DBName); 
  2. request.onsuccess = function(event) { 
  3.     //request === event.target; 
  4. request.onerror = function(event) {}  

當數據庫連接時,會返回一個IDBOpenDBRequest對象。在連接建立成功時,會觸發onsuccess事件,其中函數參數event的target屬性就是request對象。

創建和更新數據庫版本號

window.indexedDB.open的第二個參數即為版本號。在不指定的情況下,默認版本號為1。具體實例如下:

  1. const request = window.indexedDB.open(DBName, 2); 

在需要更新數據庫的schema(模式)時,需要更新版本號。此時我們指定一個高于之前版本的版本號,就會觸發onupgradeneeded事件。類似的,在***次創建時,也會觸發此事件。

我們需要注意的是,版本號是一個unsigned long long數字,這意味著它可以是一個非常大的整數。但是,它不能是一個小數,否則它將會被轉為最近的整數,同時有可能導致onUpgradeneeded事件不觸發(bug)。

構建數據庫

我們使用createObjectStore來創建一個存儲空間。同時,使用createIndex來創建索引。具體實例如下:

  1. const objectStore = db.createObjectStore('customers'); 
  2.  
  3. objectStore.createIndex('name''name', {unique:false});  

我們從***個函數createObjectStore開始說起。該函數接受兩個參數,***個參數為存儲空間的名稱,即我們上面的customers。同時,它還有第二個可選參數,keyPath指定存儲的key值為存儲對象的某個屬性,autoIncrement指定了key值是否自增(當key值為默認的從1開始到2^53的整數時)。具體實例如下:

  1. const objectStore = db.createObjectStore('customers',{keyPath:'id', autoIncrement:true}); 

第二個函數為createIndex,它的***個參數為索引的名稱,第二個參數是指定根據存儲數據的哪一個屬性來構建索引,第三個屬性unique為是否允許指定的索引值是否可以相等。具體示例如下:

  1. objectStore.createIndex('by_name''name', {unique:false}); 
  2.  
  3. objectStore.createIndex('by_email''email', {unique:true});  

當存儲空間初始化完成后,我們需要把數據放入存儲空間中,我們可以直接調用add方法將數據放入存儲空間內,具體實例如下:

  1. //方法1,規范文檔推薦使用, key值如果指定自增,可以不填 
  2. objectStore.put(data, key); 
  3. //方法2,key值同上 
  4. objectStore.add(data, key);  

事務

在IndexedDB中,我們也能夠使用事務來進行數據庫的操作。事務有三個模式:

  • readOnly,只讀
  • readwrite,讀寫
  • versionchange,數據庫版本變化

我們創建一個事務時,需要從上面選擇一種模式,如果不指定的話,則默認為只讀模式。具體實例如下:

  1. const transition = db.transition(['customers'], 'readwrite'); 

事務函數transition的***個參數為需要關聯的存儲空間,第二個可選參數為事務模式。與上面類似,事務成功時也會觸發onsuccess函數,失敗時觸發onerror函數。

事務的操作都是原子性的。

刪除

使用delete函數即可刪除數據。具體使用方法如下: 

  1. const request = db.transaction(['customers'], 'readwrite').objectStore('customers').delete(author); 

獲取數據

get方法

最簡單的方法就是使用自帶的get函數來獲取存儲空間的值,具體實例如下:

  1. db.transition(['customer']).objectStore('customer').get(keyName).onuccess = function(){}; 

游標方法

我們使用openCursor來創建游標。 

  1. const objectStore = db.transaction('customers').objectStore('customers'); 
  2.  
  3. objectStore.openCursor().onsuccess = function(event) { 
  4.   const cursor = event.target.result; 
  5.   if (cursor) { 
  6.     alert(cursor.value.name); 
  7.     cursor.continue(); 
  8.   } 
  9.   else { 
  10.     alert('No more entries!'); 
  11.   } 
  12. }; 

 使用游標時有一個需要注意的地方,當游標便利整個存儲空間但是并未找到給定條件的值時,仍然會觸發onsuccess函數。

同時,如果你想要限定你在游標中看到的值的范圍,你可以使用一個key range對象然后把它作為***個參數傳給openCursor或是openKeyCursor方法。你可以構造一個只允許一個單一key的 key range,或者一個具有下限或上限,或者一個既有上限也有下限。邊界可以是閉合的(也就是說key range包含給定的值)或者是“開放的”(也就是說key range不包括給定的值)。具體實例如下: 

  1. // 只匹配 'Donna' 
  2. const singleKeyRange = IDBKeyRange.only('Donna'); 
  3.  
  4. // 匹配所有在 'Bill' 前面的, 包括 'Bill' 
  5. const lowerBoundKeyRange = IDBKeyRange.lowerBound('Bill'); 
  6.  
  7. // 匹配所有在 “Bill” 前面的, 但是不需要包括 'Bill' 
  8. const lowerBoundOpenKeyRange = IDBKeyRange.lowerBound('Bill'true); 
  9.  
  10. // Match anything up to, but not including, 'Donna' 
  11. const upperBoundOpenKeyRange = IDBKeyRange.upperBound('Donna'true); 
  12.  
  13. //Match anything between 'Bill' and 'Donna', but not including 'Donna' 
  14. const boundKeyRange = IDBKeyRange.bound('Bill''Donna'falsetrue); 
  15.  
  16. index.openCursor(boundKeyRange).onsuccess = function(event) { 
  17.   const cursor = event.target.result; 
  18.   if (cursor) { 
  19.     // Do something with the matches. 
  20.     cursor.continue(); 
  21.   } 
  22. };  

IDBKeyRange對象的lowerBound和upperBound方法分別表示檢索指定key值前或者后的范圍(第二個參數指定邊界是否閉合,如果為true則不閉合)。

有時候你可能想要以倒序而不是正序(所有游標的默認順序)來遍歷。切換方向是通過傳遞prev到 openCursor方法來實現的。 

  1. objectStore.openCursor(null, IDBCursor.prev).onsuccess = function(event) { 
  2.   const cursor = event.target.result; 
  3.   if (cursor) { 
  4.     // Do something with the entries. 
  5.     cursor.continue(); 
  6.   } 
  7. };  

因為 “name” 索引不是***的,那就有可能存在具有相同 name 的多條記錄。要注意的是這種情況不可能發生在對象存儲空間上,因為鍵必須永遠是***的。如果你想要在游標在索引迭代過程中過濾出重復的,你可以傳遞 nextunique (或 prevunique 如果你正在向后尋找)作為方向參數。 當 nextunique 或是 prevunique 被使用時,被返回的那個總是鍵最小的記錄。

索引方法

在前面構建數據庫時,我們創建了兩個索引。現在,我們就通過這兩個索引來演示如何通過索引進行搜索。具體實例如下: 

  1. const index = objectStore.index('by_name'); 
  2. //***種,使用get方法 
  3. index.get(name).onsuccess = function(){ 
  4.     alert(event.target.result.name); 
  5. //第二種,使用游標 
  6. //普通游標 
  7. index.openCursor().onsuccess = function(event) { 
  8.   const cursor = event.target.result; 
  9.   if (cursor) { 
  10.     // cursor.key 是一個 name, 就像 'Bill', 然后 cursor.value 是整個對象。 
  11.     alert('Name: ' + cursor.key + ', id' + cursor.value.id + ', email: ' + cursor.value.email); 
  12.     cursor.continue(); 
  13.   } 
  14. }; 
  15.  
  16. //鍵游標 
  17. index.openKeyCursor().onsuccess = function(event) { 
  18.   const cursor = event.target.result; 
  19.   if (cursor) { 
  20.     // cursor.key is 一個 name, 就像 'Bill', 然后 cursor.value 是那個id,即存儲對象的key值。 
  21.     alert('Name: ' + cursor.key + ', 'id: ' + cursor.value); 
  22.     cursor.continue(); 
  23.   } 
  24. };  

異常處理

在瀏覽器有如下操作的情況下,indexedDB可能會出現異常:

  • 用戶清除瀏覽器緩存
  • 存儲空間超過大小限制

W3C規范文檔需要注意的應用點

key值能夠接受的數據類型

在IndexedDB中,key值可以接受一下幾種類型的值:

  • Number
  • Date
  • String
  • ArrayBuffer
  • Array

具體說明可以參考此處。

key path能夠接受的數據類型

在IndexedDB中,key path(主鍵)能夠接接受如下數據類型:

  • Blob
  • File
  • Array
  • StringI

注:空格不能出現在key path中。

value能夠接受的數據類型

在IndexedDB中,value能夠接受ECMA-262中所有的值,例如String,Date,ImageDate等。

事務中斷后,會不會影響key值的自增

IndexedDB在沒有指定key值的時候就會采用自增的key值,不受其他任何影響。如果一個事務在中途中斷,那么key值的自增將會從事務開始前的key開始。

IndexedDB的安全相關問題

IndexedDB也受到瀏覽器同源策略的限制。

總結

IndexedDB在本地存儲中有著無可替代的作用,是替代關系型數據庫websql的產品。在許多需要運用離線存儲的場景下,IndexedDB能夠給我們提供有效的支撐。但是,IndexedDB畢竟存在于客戶端,會出現諸如用戶清理緩存(Windows下更為常見)等破壞數據的情況,因此建議作為一個優化用戶體驗的方案,不能過多依賴。

參考文獻

后續計劃

W3C的規范文檔還在學習中。在有時間的情況下,后續可能會嘗試翻譯IndexedDB 2.0的官方文檔,如果有需要的后續可以繼續關注。有什么問題也歡迎隨時交流。

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2016-08-12 08:49:46

React NativFacebookNative

2018-07-05 11:30:56

數據庫瀏覽器IndexedDB

2012-11-15 10:18:51

IBMdw

2009-06-11 09:24:59

NetBeans入門

2012-02-15 13:26:56

IndexedDB

2012-02-15 14:21:01

IndexedDB

2013-01-14 12:53:13

Firefox OSIndexedDB

2010-01-13 17:04:36

C++語言

2010-03-30 14:46:56

CentOS學習

2011-08-31 10:12:26

MTK手機平臺

2009-04-13 11:33:25

IBMdWRational

2012-02-23 13:59:00

IndexedDB

2013-01-18 10:59:44

IBMdW

2010-01-18 16:27:26

C++語言

2009-08-25 17:49:07

C#入門

2009-07-15 17:27:30

Jython入門

2023-06-07 08:27:10

Docker容器

2011-03-25 09:18:59

Nagios

2012-02-23 15:36:51

IndexedDB

2021-02-28 20:53:37

Cookie存儲瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲有码转帖 | 欧美精品综合在线 | 精品国产欧美一区二区三区成人 | 久久久青草婷婷精品综合日韩 | 97视频久久 | 成人精品一区二区三区四区 | 亚洲一级淫片 | 国产日韩欧美精品 | 精品国产成人 | 亚洲欧美中文日韩在线v日本 | 成人精品免费视频 | 97久久久久久久久 | 免费成人午夜 | 久久久久成人精品亚洲国产 | 中文在线a在线 | 国产成人麻豆免费观看 | 中文av网站 | 高清一区二区三区 | 成人免费观看视频 | 亚洲国产成人av好男人在线观看 | 久久精品国产亚洲一区二区 | 91精品国产综合久久福利软件 | 久久精品一区 | 黄色日批视频 | 怡红院成人在线视频 | xxx视频| 成人黄色在线观看 | 国产成人99 | 一区二区三区日 | 亚洲精品色 | 宅女噜噜66国产精品观看免费 | 99精品久久久 | 国产精品久久久久av | 狠狠色狠狠色综合日日92 | 超碰在线播| 成人免费淫片aa视频免费 | 久久久久国产一区二区三区不卡 | 国产精品国产三级国产aⅴ无密码 | 久久69精品久久久久久久电影好 | 四虎影院久久 | 成人h动漫亚洲一区二区 |