概述
IndexedDB 是一個事務型資料庫系統,類似於基於 SQL 的 RDBMS。 然而不同的是它使用固定列表,IndexedDB 是一個基於 JavaScript 的物件導向的資料庫。
現有的瀏覽器資料儲存方案,都不適合儲存大量資料:Cookie 的大小不超過 4KB,且每次請求都會傳送回伺服器 LocalStorage 在 2.5MB 到 10MB 之間(各家瀏覽器不同),而且不提供搜尋功能,不能建立自定義的索引。所以,需要一種新的解決方案,這就是 IndexedDB 誕生的背景
簡單來說,IndexedDB 就是瀏覽器提供的本地資料庫。
IndexedDB 具有以下特點
- 鍵值對儲存
- 非同步操作(避免鎖死瀏覽器)
- 支援事務
- 同源限制(協議+域名+埠)
- 儲存空間大
- 支援二進位制儲存(ArrayBuffer 物件和 Blob 物件,可儲存檔案資料)
基本概念
對比關聯式資料庫 MySql 可以得到以下關係
- 資料庫:IDBDatabase
- 表格:物件倉庫(IDBObjectStore)
- 行資料:物件倉庫儲存的一條資料
- 索引:IDBindex,加速資料的檢索(在物件倉庫裡面可為不同的鍵建立)
- 事務:IDBTransaction
- 操作請求:IDBRequest
- IDBCursor:遍歷物件儲存空間和索引
- IDBKeyRange:定義鍵的範圍資料
基本操作
相容性注意點
// 全域性變數相容性問題
window.indexedDB =
window.indexedDB ||
window.mozIndexedDB ||
window.webkitIndexedDB ||
window.msIndexedDB;
window.IDBTransaction =
window.IDBTransaction ||
window.webkitIDBTransaction ||
window.msIDBTransaction;
window.IDBKeyRange =
window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
if (!window.indexedDB) {
window.alert(
"Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available."
);
}
複製程式碼
資料庫操作
開啟/新建資料庫
var databaseName = "MyTestDatabase";
var databaseVersion = 1;
// 開啟資料庫
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log("open success");
};
request.onerror = function(event) {
console.log("open fail");
};
request.onupgradeneeded = function(event) {};
複製程式碼
window.indexedDB.open
函式開啟對應的資料庫,如果沒有該資料庫就會新建。
新建資料庫
或者資料庫版本
大於當前版本會觸發onupgradeneeded
事件
資料庫為什麼會有版本?
因為資料庫的資料解構可能會發生改變的
,所以一般修改資料解構的操作在onupgradeneeded
裡面書寫
刪除資料庫
window.indexedDB.deleteDatabase(databaseName);
複製程式碼
物件倉庫操作(表格操作)
建立和修改表格是修改資料庫的資料解構
,所以我把他們寫在onupgradeneeded
事件裡
建立表格
request.onupgradeneeded = function(event) {
console.log("onupgradeneeded");
db = event.target.result;
// 建立倉庫物件(建立表格)
// 這裡我將主鍵設定為id
var objectStore = db.createObjectStore(objectStoreName, {
keyPath: "id",
autoIncrement: true
});
};
複製程式碼
刪除表格
request.onupgradeneeded = function(event) {
console.log("onupgradeneeded");
db = event.target.result;
// 刪除倉庫物件(刪除表格)
db.deleteObjectStore(objectStoreName);
};
複製程式碼
資料操作(行資料操作)
新增資料(增)
var databaseName = "MyTestDatabase";
var databaseVersion = 1;
var db;
var objectStoreName = "objectStore1";
var storeDatas = [
{ id: "1", name: "張三", age: 18 },
{ id: "2", name: "李四", age: 19 }
];
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log("open success");
db = event.target.result;
// 將資料儲存到新建的物件倉庫
var objectStore = db
.transaction([objectStoreName], "readwrite")
.objectStore(objectStoreName);
storeDatas.forEach(function(dataItem) {
// 新增一條資料
objectStore.add(dataItem);
});
};
複製程式碼
刪除資料(刪)
var databaseName = "MyTestDatabase";
var databaseVersion = 1;
var db;
var objectStoreName = "objectStore1";
var storeDatas = [
{ id: "1", name: "張三", age: 18 },
{ id: "2", name: "李四", age: 19 }
];
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log("open success");
db = event.target.result;
console.log("刪除資料");
var req = db
.transaction([objectStoreName], "readwrite")
.objectStore(objectStoreName)
.delete("2"); // 這裡的“2”指定的是主鍵的鍵值
req.onsuccess = function() {
console.log("刪除成功");
};
req.onerror = function() {
console.log("刪除失敗");
};
};
複製程式碼
修改資料(改)
console.log("更新資料");
var req = db
.transaction([objectStoreName], "readwrite")
.objectStore(objectStoreName)
.put({
id: "2",
name: "王五",
age: 17
}); // 將整條資料給替換
req.onsuccess = function() {
console.log("更新成功");
};
req.onerror = function() {
console.log("更新失敗");
};
複製程式碼
獲取資料(查)
console.log("讀取資料");
var req = db
.transaction([objectStoreName], "readonly")
.objectStore(objectStoreName)
.get("1"); // 這裡的“1”也是主鍵的鍵值
req.onsuccess = function() {
console.log("獲取成功");
console.log(req.result);
};
req.onerror = function() {
console.log("獲取失敗");
};
複製程式碼
通過指標物件遍歷表格資料
console.log("遍歷資料");
var objectStore = db
.transaction([objectStoreName], "readonly")
.objectStore(objectStoreName);
var count = 0;
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(`第${++count}條資料為`);
console.log(cursor.value);
cursor.continue(); // 將指標移動下一個位置
} else {
console.log("沒有更多資料");
}
};
複製程式碼
小結
indexedDB的API還是非常多的,這裡只是簡單介紹了最常用的幾個操作(個人認為^_^)。