indexedDB入門

概述

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還是非常多的,這裏只是簡單介紹了最常用的幾個操作(個人認爲^_^)。

參考文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章