HTML5 本地存储 IndexedDB 教程

HTML5 herman 661浏览 0评论

HTML5 的一个重要特性是本地数据持久性,它使用户能够在线和离线访问 Web 应用程序。此外,本地数据持久性使移动应用程序更灵敏,使用的带宽更少,而且能够在低带宽场景中更高效地工作。HTML5 提供了一些本地数据持久性选项。第一个选项是 localstorage,它支持您使用一个简单的键值对来存储数据。IndexedDB(一个更加强大的选项)支持您本地存储大量对象,并使用健壮的数据访问机制检索数据。

IndexedDB API 取代了 Web Storage API,后者在 HTML5 规范中已不推荐使用。(但一些领先的浏览器仍然支持 Web Storage,其中包括苹果公司的 Safari 和 Opera Web 浏览器)与 Web Storage 相比,IndexedDB 具有多个优势,其中包括索引、事务处理和健壮的查询功能。本文将通过一系列的示例来展示如何管理 IndexedDB 数据库。

IndexedDB

对于只存储某些字段的需求来说,可以使用Local Storage和 Session Storage来完成。但是一旦存储大量的数据,Local Storage和 Session Storage就远远不能满足需求了。这时,IndexedDB的强大之处就会体现出来了。

创建或连接数据库

IndexedDB(name, version, callbackObject = {});
  • name : 创建或者连接的数据库名
  • version : 数据库版本号
  • callbackObject: 配置回调函数

callbackObject 支持以下的回调函数配置:

  • success:创建或者连接的数据库成功后的回调函数
  • error:创建或者连接的数据库失败后的回调函数
  • upgradeneeded:数据库版本号更新后的回调函数
/* 对不同浏览器的indexedDB进行兼容 */
const indexeddb = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
/* 创建或连接数据库 */
const request = indexeddb.open(name, version);  // name:数据库名,version:数据库版本号
IndexedDB(name, version, {
    success: function(et){
        const db = this.db; // 数据库实例
    }
});

连接到数据库的回调函数

request.addEventListener('success', function(event){ 
    // 打开或创建数据库成功
}, false);

request.addEventListener('error', function(event){ 
    // 打开或创建数据库失败
}, false);

request.addEventListener('upgradeneeded', function(event){ 
    // 更新数据库时执行
}, false);

在连接到数据库后,request会监听三种状态:

  • success:打开或创建数据库成功
  • error:打开或创建数据库失败
  • upgradeneeded:更新数据库
    upgradeneeded状态是在indexedDB创建新的数据库时和indexeddb.open(name, version) version(数据库版本号)发生变化时才能监听到此状态。当版本号不发生变化时,不会触发此状态。数据库的ObjectStore的创建、删除等都是在这个监听事件下执行的。

创建、删除ObjectStore

在indexedDB中,ObjectStore类似于数据库的表。

request.addEventListener('upgradeneeded', function(event){ 
    // 创建数据库实例
    const db = event.target.result;

    // 关闭数据库
    db.close();
    
    // 判断是否有ObjectStore
    db.objectStoreNames.contains(objectStoreName);
    
    // 删除ObjectStore
    db.deleteObjectStore(objectStoreName);
    
}, false);

可以用如下方法创建一个ObjectStore

request.addEventListener('upgradeneeded', function(event){ 
    // 创建数据库实例
    const db = event.target.result;
    // 判断是否有ObjectStore
    if(!db.objectStoreNames.contains(objectStoreName)){
        const store = db.createObjectStore(objectStoreName, {
            keyPath: keyPath  // keyPath 作为ObjectStore的搜索关键字
        });
        // 为ObjectStore创造索引
        store.createIndex(name,    // 索引
                          index,   // 键值
                          {
                              unique: unique  // 索引是否唯一
                          });
    }
}, false);

数据的增删改查

request.addEventListener('success', function(event){ 
    // 创建数据库实例
    const db = event.target.result;
    
    // 查找一个ObjectStore
    db.transaction(objectStoreName, wa);
    // wa为'readwrite'时,数据可以读写 
    // wa为'readonly'时,数据只读
    const store = transaction.objectStore(objectStoreName);
}, false);

数据库的增删改查:

// 添加数据,当关键字存在时数据不会添加
store.add(obj);
// 更新数据,当关键字存在时覆盖数据,不存在时会添加数据
store.put(obj);
// 删除数据,删除指定的关键字对应的数据
store.delete(value);
// 清除ObjectStore
store.clear();
// 查找数据,根据关键字查找指定的数据
const g = store.get(value);
g.addEventListener('success', function(event){
    // 异步查找后的回调函数
}, false);

按索引查找数据

const index = store.index(indexName);
const cursor = index.openCursor(range);
cursor.addEventListener('success', function(event){
    const result = event.target.result;
    if(result){
        result.value       // 数据
        result.continue(); // 迭代,游标下移
    }
}, false);

按索引的范围查找数据

const index = store.index(indexName);
const cursor = index.openCursor(range);
/**
 * range为null时,查找所有数据
 * range为指定值时,查找索引满足该条件的对应的数据
 * range为IDBKeyRange对象时,根据条件查找满足条件的指定范围的数据
 */

// 大于或大于等于 
range = IDBKeyRange.lowerBound(value, true)   // (value, +∞),>  value
range = IDBKeyRange.lowerBound(value, false)  // [value, +∞),>= value
// 小于或小于等于,isOpen:true,开区间;false,闭区间
range = IDBKeyRange.upperBound(value, isOpen)
// 大于或大于等于value1,小于或小于等于value2
IDBKeyRange.bound(value1, value2, isOpen1, isOpen2)

删除数据库

IndexedDB.deleteDatabase(databaseName);

关闭数据库

this.close(time);

判断是否有ObjectStore

this.hasObjectStore(objectStoreName);

创建ObjectStore

this.createObjectStore(objectStoreName, keyPath, indexArray);

indexArray(Array),里面的对象为(Object)

  • index: 索引
  • name: 键值

删除ObjectStore

this.deleteObjectStore(objectStoreName);

获取ObjectStore

this.getObjectStore(objectStoreName, writeAble = true);

举例如下:

IndexedDB(name, version, {
    success: function(){
        const db = this.db;                                 // 数据库实例
        const store = this.getObjectStore(objectStoreName); // ObjectStore实例
    }
});

添加数据

store.add(obj);

Object或Array,下同。

修改数据

store.put(obj);

删除数据

store.delete(value);

String、Number或Array。

查找数据

store.get(key, callback);

callback回调函数。回调参数为result。

清除ObjectStore

store.clear();

游标

store.cursor(indexName, [range,] callback);

range用来选择范围。
根据字符串返回游标查询的范围,例如:

  • '5' 等于
  • '> 5' 大于
  • '>= 5' 大于等于
  • '< 5' 小于
  • '<= 5' 小于等于
  • '[5, 8]' 闭区间
  • '(5, 8)' 开区间

callback回调函数。回调参数为result,result.value为获取的数据,result.continue()迭代。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763,QQ2群:454796847,QQ3群:187424846。QQ群进群密码:xttblog,想加微信群的朋友,可以微信搜索:xmtxtt,备注:“xttblog”,添加助理微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » HTML5 本地存储 IndexedDB 教程