新建 indexedDB 資料庫並插入資料
一、什麼叫資料庫
DB的全名是database,即資料庫。
二、資料庫的種類
資料庫有兩種型別,分別是關係型資料庫和非關係型資料庫。
- 關係型資料庫:Oracle、DB2、MicrosoftSQLServer、MicrosoftAccess、MySQL等。
- 非關係型資料庫:NoSql、Cloudant、MongoDb、redis、HBase等。
關係型資料庫的優點:
- 能夠複雜查詢:可以用SQL句子便捷的在一個表及多個表之間做複雜的資料查詢。
- 事務支援性優秀:能夠實現對於安全性要求很高的資料訪問。
非關係型資料庫的優點:
- 效能好:NOSQL是基於鍵值對的,可以想象成表中的主鍵和值的對應關係,並且不用通過SQL層的解析,因此效能表現優異。
- 可擴充套件性好:同樣也是基於鍵值對,資料間耦合度低,因此很容易水平擴充套件。
- SQL(Structured Query Language) 是一種資料庫語言。
- 就資料庫型別而言,IndexedDB 不屬於關係型資料庫(不支援 SQL 查詢語句),更接近 NoSQL 資料庫。
IndexedDB 具有以下特點
(1)鍵值對儲存。IndexedDB 內部採用物件倉庫(object store)存放資料。所有型別的資料都可以直接存入,包括 JavaScript 物件。物件倉庫中,資料以"鍵值對"的形式儲存,每一個數據記錄都有對應的主鍵,主鍵是獨一無二的,不能有重複,否則會丟擲一個錯誤。
(2)非同步。IndexedDB 操作時不會鎖死瀏覽器,使用者依然可以進行其他操作,這與 LocalStorage 形成對比,後者的操作是同步的。非同步設計是為了防止大量資料的讀寫,拖慢網頁的表現。
(3)支援事務。IndexedDB 支援事務(transaction),這意味著一系列操作步驟之中,只要有一步失敗,整個事務就都取消,資料庫回滾到事務發生之前的狀態,不存在只改寫一部分資料的情況。
(4)同源限制IndexedDB 受到同源限制,每一個數據庫對應建立它的域名。網頁只能訪問自身域名下的資料庫,而不能訪問跨域的資料庫。
(5)儲存空間大IndexedDB 的儲存空間比 LocalStorage 大得多,一般來說不少於 250MB,甚至沒有上限。
(6)支援二進位制儲存。IndexedDB 不僅可以儲存字串,還可以儲存二進位制資料(ArrayBuffer 物件和 Blob 物件)。
- 資料庫
- 每個資料庫包含若干個物件倉庫(object store)。它類似於關係型資料庫的表格。
- 物件倉庫儲存的是資料記錄。每條記錄類似於關係型資料庫的行,但是隻有主鍵和資料體兩部分。
- 資料哭 > 物件倉庫 > 資料記錄
操作流程
-
開啟資料庫:indexedDB.open()
var version = 1; var databaseName = "database"; var request = window.indexedDB.open(databaseName, version);//這是一個非同步操作,但是會立刻返回一個IDBOpenDBRequest物件。方法返回一個IDBRequest物件。這個物件通過三種事件error、success、upgradeneeded處理開啟資料庫的操作結果。 var db; /** * 新建資料庫與開啟資料庫是同一個操作。 * 如果要開啟的資料庫不存在,則會先新建資料庫: * 1. 新建資料庫時呼叫 request.onupgradeneeded(因為這時版本從無到有,所以會觸發這個事件) * 2. 把資料庫版本設為 1 * 3. 此時資料庫物件 db = e.target.result; * 新建資料庫後,就可以開啟資料庫了,所以繼續呼叫 request.onsuccess * */ request.onupgradeneeded = function(e) { db = e.target.result; console.log("onupgrageneeded"); // 通常新建資料庫以後,第一件事是新建物件倉庫(即新建表),並設定主鍵 var objectStore = db.createObjectStore("person", { keyPath: "id" //設定主鍵為 id }); } /** * 如果要開啟的資料庫存在,則會直接開啟該資料庫 * 此時資料庫物件 db = request.result; * */ request.onsuccess = function(e) { db = request.result; console.log("success"); } /** * 資料庫開啟錯誤時呼叫此回撥函式 * */ request.onerror = function(e) { console.log("error"); }
-
新建資料庫:
新建資料庫與開啟資料庫是同一個操作。如果指定的資料庫不存在,就會新建。
a. 新建物件倉庫(即新建表)。
request.onupgradeneeded = function(e) { db = e.target.result; console.log("onupgrageneeded"); // 通常,新建資料庫以後,第一件事是新建物件倉庫(即新建表),並設定主鍵 var objectStore = db.createObjectStore("person", { keyPath: "id" //設定主鍵為 id }); }
b. 更好的寫法是先判斷一下,這張表格是否存在,如果不存在再新建。
request.onupgradeneeded = function(e) { db = e.target.result; console.log("onupgrageneeded"); // 通常新建資料庫以後,第一件事是新建物件倉庫(即新建表),並設定主鍵 var objectStore; if(!db.objectStoreNames.contains(databaseName)) {//如果這個 物件倉庫/表 不存在,就新建 objectStore = db.createObjectStore("person", { keyPath: "id" //設定主鍵為 id }); } }
c.如果資料記錄裡面沒有合適作為主鍵的屬性,可以讓 IndexedDB 自動生成主鍵。
var objectStore = db.createObjectStore("person", { autoIncrement: true }); //指定主鍵為一個遞增的整數
-
新增資料:
新增資料指的是向物件倉庫寫入資料記錄。這需要通過事務完成。var obj1 = {id:1,name:"張三",age:24,email:"[email protected]"}; var obj2 = {id:2,name:"李四",age:30,email:"[email protected]"}; function addRecord(obj){ var request = db.transaction(["person"],"readwrite") //寫入資料需要新建一個事務。新建時必須指定表格名稱和操作模式(“只讀”或“讀寫”) .objectStore("person") //新建事務以後,通過IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 物件 .add(obj); //再通過表格物件的add()方法,向表格寫入一條記錄 request.onsuccess = function(e){ console.log("資料寫入成功"); } request.onerror = function(e){ console.log("資料寫入失敗"); } } window.onload = function(){ addRecord(obj1); addRecord(obj2); }
注意:不加window.onload 可能存在非同步問題,報undefined錯誤。
執行過程式碼後如果物件倉庫仍是空,重新整理一下即可:
參考文章:
[1]https://www.shulanxt.com/doc/dbdoc/db-intro
[2]http://www.ruanyifeng.com/blog/2018/07/indexeddb.html
[3]https://wangdoc.com/javascript/bom/indexeddb.html
[4]https://www.bilibili.com/video/BV15J411H7GH