本地数据存储之 IndexedDB 实践

标签: 本地存储 indexeddb localstorage | 发表时间:2014-12-10 14:19 | 作者:王铁手
出处:http://segmentfault.com/blogs

本地存储的类型

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

  • Web Sql
  • IndexedDB
  • Local Storage
  • Session Storage
  • Cookies
  • Application Cache

项目需求

  • 离线存储读取数据
  • 允许用户对数据进行增删改操作
  • 数据存储在本地,不依赖后端
  • 数据支持索引查询

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

IndexedDB 数据库的使用

定义数据库对象

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

数据库初始化

  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});
        }
    };
}

关闭数据库

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

删除数据库

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

数据库表的 CURD

  • 添加数据

        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
                })
            }
        }
    }
    
  • 删除数据

        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();
          };
      }
      
    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: 实现细节部分待有时间进行补充完善~

相关 [数据 indexeddb 实践] 推荐:

本地数据存储之 IndexedDB 实践

- - SegmentFault 最新的文章
本地存储主要有以下几种:. 允许用户对数据进行增删改操作. 数据存储在本地,不依赖后端. 由于 WebSQL 在标准上还存在争议,而 localStorage 实现数据分页、查询比较复杂,最终考虑使用了 IndexedDB 来满足需求. IndexedDB 数据库的使用. ps: 实现细节部分待有时间进行补充完善~.

C++ 工程实践(9):数据抽象

- roc - 博客园-陈硕的 Blog
陈硕 (giantchen_AT_gmail). 陈硕关于 C++ 工程实践的系列文章: http://blog.csdn.net/Solstice/category/802325.aspx. 排版正常的版本: http://www.cnblogs.com/Solstice/category/287661.html.

数据库设计的最佳实践

- - CSDN博客数据库推荐文章
1、使用定义明确的表或列名,并保持一致(例如,School、StudentCourse、CourseID). 2、使用单数形式的表名(即,用StudentCourse而非StudentCourses). 表代表了实体的合集,不需要复数形式. 否则你将在定义表时不得不使用“{”、“[”等字符(即为了访问表Student Course,你须得书写“Student Course”.

大数据分析最佳实践

- - 互联网分析
   转自:TTNN   Q先生杰作. 大概是从今年开始,big data一词逐渐成为术语,这跟整个世界的数据爆发当然有关系. 以前,人们喜欢用海量数据这个词,large-scale. 这看上去还是显得有点学术气, 像是BI人自己关起门来说自己的宝贝. 而big data更显通俗,在各行各业都显现出的一种势头,于是产生这个更加简单的词汇,大数据.

Spring+MyBatis实践——MyBatis访问数据库

- - 开源软件 - ITeye博客
    在http://dufengx201406163237.iteye.com/blog/2102054中描述了工程的配置,在此记录一下如何使用MyBatis访问数据库;. . .

数据库优化的最佳实践

- - ITeye博客
  选择合理的索引(前缀性及可选性)、删除没有用的索引.    2)使用规范化,但不要使用过头.   规范化(至少是第三范式)是一个易于理解且标准的方法. 然而,在有些情况下,你可能希望违反这些规则. 查询表通常是规范化的产物,也就是说,你创建了一个特殊的表,这个表包含了在其他表中被频繁使用的相关信息的列表.

MySQL数据库优化实践

- - OurMySQL
   最近一段时间,我们整理了一些关于Percona,Linux,Flashcache,硬件设备的优化经验,分享给大家:.     1.开启BBWC.    RAID卡都有写cache(Battery Backed Write Cache),写cache对IO性能的提升非常明显,因为掉电会丢失数据,所以必须由电池提供支持.

有赞数据中台建设实践

- - IT瘾-dev
概述究竟什么是中台, 业界并没有一个标准答案, 各个厂商都有自己的定义. 笔者比较认可的一个定义是 ThoughtWorks 提出的"企业级能力复用平台". 各个领域涌现出很多中台产品, 如业务中台, 搜索中台, 数据中台等. 其中数据中台这个词汇越来越多的出现在视野中, 从百度指数中可以看到这一趋势.

MyCat 数据库实践注意事项

- - 掘金后端
最近两周研究了一下 MyCat ,下载了一份官方的实践指南,搜了几篇部署介绍,启动了三个虚拟机节点,然后就开始了验证过程. 毕竟不是专业 DBA,我的首要目标是弄清楚如何部署,产品从普通 MySQL 数据库迁移到 MyCat 需要注意的事项. 抓主要矛盾,了解关键技术点,解决关键疑惑,有一本书叫《关键20小时,快速学会任何技能》,跟它的核心思想类似.