indexedDB入門

概述

IndexedDB 是一個事務型數據庫系統,相似於基於 SQL 的 RDBMS。 然而不一樣的是它使用固定列表,IndexedDB 是一個基於 JavaScript 的面向對象的數據庫。

現有的瀏覽器數據儲存方案,都不適合儲存大量數據:Cookie 的大小不超過 4KB,且每次請求都會發送回服務器 LocalStorage 在 2.5MB 到 10MB 之間(各家瀏覽器不一樣),並且不提供搜索功能,不能創建自定義的索引。因此,須要一種新的解決方案,這就是 IndexedDB 誕生的背景javascript

簡單來講,IndexedDB 就是瀏覽器提供的本地數據庫。html

IndexedDB 具備如下特色java

  • 鍵值對儲存
  • 異步操做(避免鎖死瀏覽器)
  • 支持事務
  • 同源限制(協議+域名+端口)
  • 存儲空間大
  • 支持二進制存儲(ArrayBuffer 對象和 Blob 對象,可存儲文件數據)

基本概念

對比關係數據庫 MySql 能夠獲得如下關係web

  • 數據庫: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仍是很是多的,這裏只是簡單介紹了最經常使用的幾個操做(我的認爲^_^)。函數

參考文檔

相關文章
相關標籤/搜索