前端开发您现在的位置是:首页 > 博客日志 > 前端开发

本地数据存储之 IndexedDB 实践

<a href='mailto:'>微wx笑</a>的头像微wx笑 2024-01-01前端开发 0 0关键字:   

本地存储的类型本地存储主要有以下几种:Web SqlIndexedDBLocal StorageSession StorageCookiesApplication Cache项目需求离线存储读取数据允许用户对数据进行增删改操作数据

本地存储的类型

本地存储主要有以下几种:yOw无知

  • Web SqlyOw无知

  • IndexedDByOw无知

  • Local StorageyOw无知

  • Session StorageyOw无知

  • CookiesyOw无知

  • Application CacheyOw无知

项目需求

  • 离线存储读取数据yOw无知

  • 允许用户对数据进行增删改操作yOw无知

  • 数据存储在本地,不依赖后端yOw无知

  • 数据支持索引查询yOw无知

由于 WebSQL 在标准上还存在争议,而 localStorage 实现数据分页、查询比较复杂,最终考虑使用了 IndexedDB 来满足需求。yOw无知

IndexedDB 支持情况

图片描述yOw无知

IndexedDB 数据库的使用

定义数据库对象

var wxbDB = {    name   : "wxb",    version: 1,
    db     : null};

此处我们定义了一个数据库对象,包括name 数据库名称,version 数据库的版本,以及 db 数据对象。yOw无知

数据库初始化

function initDB(dbObj) {
    dbObj.version = dbObj.version || 1;    var request = indexedDB.open(dbObj.name, dbObj.version);
    request.onerror = function (e) {
        console.log(e.currentTarget.error.message);
    };
    request.onsuccess = function (e) {
        dbObj.db = e.target.result;
    };
    request.onupgradeneeded = function (e) {        var thisDB = e.target.result;        if (!thisDB.objectStoreNames.contains("material")) {            var objStore = thisDB.createObjectStore("material", {keyPath: "id", autoIncrement: true});
            objStore.createIndex("wxid", "wxid", {unique: true});
        }        if (!thisDB.objectStoreNames.contains("account")) {            var objStore = thisDB.createObjectStore("account", {keyPath: "id", autoIncrement: true});
            objStore.createIndex("wxid", "wxid", {unique: true});
            objStore.createIndex("nickName", "nickName", {unique: false});
        }
    };
}

indexedDB.open 方法可以创建或者打开一个 IndexedDB,并返回 IDBOpenDBRequest 对象。yOw无知

IDBOpenDBRequest 对象除了onerror 和 onsuccess,还有一个类似回调函数句柄 onupgradeneeded。这个句柄在我们请求打开的数据库的版本号和已经存在的数据库版本号不一致的时候调用。yOw无知

indexedDB.open 方法的第二个可选参数是数据库版本号,数据库创建的时候默认版本号为 1,当我们传入的版本号和数据库当前版本号不一致时 onupgradeneeded 就会被调用,当然我们不能试图打开比当前数据库版本低的version,否则调用的就是 onerror 了。yOw无知

onupgradeneeded 被调用时,我们可以做一些建表、索引等操作。yOw无知

有了数据库后我们自然希望创建一个表用来存储数据,但 indexedDB 中没有表的概念,而是 objectStore,一个数据库中可以包含多个 objectStoreobjectStore 是一个灵活的数据结构,可以存放多种类型数据。yOw无知

我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore 可以存储的数据结构也有差异。yOw无知

  • 不使用 :任意值,但是没添加一条数据的时候需要指定键参数yOw无知

  • keyPath : Javascript 对象,对象必须有一属性作为键值yOw无知

  • keyGenerator : 任意值yOw无知

  • 都使用 : Javascript 对象,如果对象中有 keyPath 指定的属性则不生成新的键值,如果没有自动生成递增键值,填充 keyPath 指定属性yOw无知

图片描述yOw无知

关闭数据库

function closeDB(dbObj) {
    dbObj.db.close();
}

删除数据库

function deleteDB(dbObj) {
    indexedDB.deleteDatabase(dbObj.name);
}

数据库表的 CURD

在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些 object storeyOw无知

事务具有三种模式yOw无知

  • 只读:read,不能修改数据库数据,可以并发执行yOw无知

  • 读写:readwrite,可以进行读写操作yOw无知

  • 版本变更:verionchangeyOw无知

  • 添加数据

    function addData(dbObj, tableName, data, cb) {    var transaction = dbObj.db.transaction(tableName, 'readwrite');
        transaction.oncomplete = function () {        console.log("transaction complete");
        };
        transaction.onerror = function (event) {        console.dir(event)
        };    var objectStore = transaction.objectStore(tableName);    var request = objectStore.add(data);
        request.onsuccess = function (e) {        if (cb) {
                cb({                error: 0,                data : data
                })
            }
        };
        request.onerror = function (e) {        if (cb) {
                cb({                error: 1
                })
            }
        }
    }

插入数据yOw无知

读取数据yOw无知

  • 删除数据

    function deleteData(dbObj, tableName, id, cb) {    var transaction = dbObj.db.transaction(tableName, 'readwrite');
        transaction.oncomplete = function () {        console.log("transaction complete");
        };
        transaction.onerror = function (event) {        console.dir(event)
        };    var objectStore = transaction.objectStore(tableName);    var request = objectStore.delete(parseInt(id));
        request.onsuccess = function (e) {        if (cb) {            cb({                error: 0,
                    data : parseInt(id)
                })
            }
        };
        request.onerror = function (e) {        if (cb) {            cb({                error: 1
                })
            }
        }
    }
  • 查询数据

    1. 获取全部数据
      function getDataAll(dbObj, tableName, cb) {    var transaction = dbObj.db.transaction(tableName, 'readonly');
          transaction.oncomplete = function () {        console.log("transaction complete");
          };
          transaction.onerror = function (event) {        console.dir(event)
          };    var objectStore = transaction.objectStore(tableName);    var rowData = [];
          objectStore.openCursor(IDBKeyRange.lowerBound(0)).onsuccess = function (event) {        var cursor = event.target.result;        if (!cursor && cb) {
                  cb({                error: 0,                data : rowData
                  });            return;
              }
              rowData.push(cursor.value);
              cursor.continue();
          };
      }

      图片描述yOw无知

    2. 根据 id 获取数据

      function getDataById(dbObj, tableName, id, cb) {    var transaction = dbObj.db.transaction(tableName, 'readwrite');
          transaction.oncomplete = function () {        console.log("transaction complete");
          };
          transaction.onerror = function (event) {        console.dir(event)
          };    var objectStore = transaction.objectStore(tableName);    var request = objectStore.get(id);
          request.onsuccess = function (e) {        if (cb) {
                  cb({                error: 0,                data : e.target.result
                  })
              }
          };
          request.onerror = function (e) {        if (cb) {
                  cb({                error: 1
                  })
              }
          }
      }
    3. 根据关键词索引获取数据

      function getDataBySearch(dbObj, tableName, keywords, cb) {
          var transaction = dbObj.db.transaction(tableName, 'readwrite');    transaction.oncomplete = function () {
              console.log("transaction complete");
          };    transaction.onerror = function (event) {
              console.dir(event)
          };
      
          var objectStore = transaction.objectStore(tableName);
          var boundKeyRange = IDBKeyRange.only(keywords);
          var rowData;
          objectStore.index("nickName").openCursor(boundKeyRange).onsuccess = function (event) {
              var cursor = event.target.result;        if (!cursor) {            if (cb) {
                      cb({
                          error: 0,
                          data : rowData
                      })
                  }            return;
              }
              rowData = cursor.value;        cursor.continue();
          };
      }
    4. 根据页码获取数据

      function getDataByPager(dbObj, tableName, start, end, cb) {
          var transaction = dbObj.db.transaction(tableName, 'readwrite');    transaction.oncomplete = function () {
              console.log("transaction complete");
          };    transaction.onerror = function (event) {
              console.dir(event)
          };
      
          var objectStore = transaction.objectStore(tableName);
          var boundKeyRange = IDBKeyRange.bound(start, end, false, true);
          var rowData = [];
          objectStore.openCursor(boundKeyRange).onsuccess = function (event) {
              var cursor = event.target.result;        if (!cursor && cb) {
                  cb({
                      error: 0,
                      data : rowData
                  });            return;
              }
              rowData.push(cursor.value);        cursor.continue();
          };
      }
  • 更新数据

    function updateData(dbObj, tableName, id, updateData, cb) {    var transaction = dbObj.db.transaction(tableName, 'readwrite');
        transaction.oncomplete = function () {        console.log("transaction complete");
        };
        transaction.onerror = function (event) {        console.dir(event)
        };    var objectStore = transaction.objectStore(tableName);    var request = objectStore.get(id);
        request.onsuccess = function (e) {        var thisDB = e.target.result;        for (key in updateData) {
                thisDB[key] = updateData[key];
            }
            objectStore.put(thisDB);        if (cb) {
                cb({                error: 0,                data : thisDB
                })
            }
        };
        request.onerror = function (e) {        if (cb) {
                cb({                error: 1
                })
            }
        }
    }

ps: 实现细节部分待有时间进行补充完善~yOw无知

转自:https://segmentfault.com/a/1190000002416903 yOw无知


yOw无知

本文为转载文章,版权归原作者所有,不代表本站立场和观点。

很赞哦! () 有话说 ()

上一篇:jQuery选择表格中的列

下一篇:返回列表

相关文章