在现代浏览器的本地存储方案中,indexedDB 是一项重要的能力组成,它是可以在浏览器端使用的本地数据库,可以存储大量数据,提供接口来查询,还可以建立索引,这些都是其他存储方案 Cookie 或者 LocalStorage 无法提供的能力 。单从数据库类型来看,IndexedDB 是一个非关系型数据库(不支持通过 SQL 语句操作) 。
IndexedDB 的主要概念
IndexedDB 是一个比较复杂的 API 组合,学习它的过程就相当于学习它的各个对象 API 接口,包括以下这些( IDB 指当前操作的数据库实例 ):
- 数据库:IDBDatabase 对象
- 仓库对象: IDBObjectStore 对象
- 索引:IDBIndex 对象
- 事务:IDBTransaction 对象
- 操作请求:IDBRequest 对象
- 指针:IDBCursor 对象
- 主键:IDBKeyRange 对象
在这些 API 中包含一些主要概念:
- 数据库:数据库是所有相关数据的基本容器 。在同源策略( 协议 + 域名 + 端口 )的前提下,每个域名下可以新建任意多的数据库 。IndexedDB 中有版本概念,这就规定了同一时刻下只有一个版本的数据库存在 。
- 对象仓库:对象仓库 ObjectStore 在 IndexedDB 中对应的是 MySQL 中的表 Table 。
- 数据:对象仓库中记录的是若干条数据,数据只有主键和数据体两个部分,主键不能重复,可以为自增的整数编号或者数据中指定的一个属性 。数据体可以是任意数据类型,不限于对象 。
- 索引:为不同的属性建立索引可以加快数据的检索 。
- 事务:数据的 CURD (增删查改) 都要通过事务来完成 。
通过简单的对比图来理解 IndexedDB 的概念:

文章插图
快速起步 IndexedDB
在介绍了 IndexedDB 的主要概念之后,可以通过一个简单实用的 CURD 例子来学习在日常开发中我们是怎么使用 IndexedDB 的,各个 API 细节日后可以慢慢深入学习 。
- 必不可少的浏览器支持检查:
if(!('indexedDB' in window)){ console.log('当前浏览器支持 IndexedDB'); return;} else { console.log('您的浏览器不支持 IndexedDB') // todo 建议升级或者更换其他浏览器}
- 连接数据库
// 数据库实例let db;// 数据库打开操作,第一个参数是数据库名称, 第二个参数是数据库版本let DBRequestLink = window.indexedDB.open('dataBaseName', 1)DBRequestLink.onsuccess = function(event) { // 获取数据库实例 db = DBRequestLink.result; // 其他操作};// 这个监听回调触发于数据库首次新建、open数据库时传递新版本(只能比之前传递的版本高)DBRequestLink.onupgradeneeded = function(event) {};
- 创建数据库的主键和字段
DBOpenRequest.onupgradeneeded = function(event) { let db = event.target.result; // 创建一个数据库存储对象,并指定主键 let objectStore = db.createObjectStore('person', {keyPath: 'id', autoIncrement: true }); /* 定义存储对象的数据项* 第一个参数是创建的索引名称,可以为空 * 第二个参数是索引使用的关键名称,可以为空 * 第三个参数是可选配置参数,可以不传,常用参数之一就是 unique,表示该字段是否唯一,不能重复 */objectStore.createIndex('id', 'id', { unique: true}); objectStore.createIndex('name', 'name'); objectStore.createIndex('age', 'age'); objectStore.createIndex('sex', 'sex');};
- 在上述操作中,我们先定义了上文中提到的 IDBObjectStore 对象,并指定主键为 id,随后又通过 createIndex 来创建字段 。值得注意的是虽然创建了四个字段,但在 IndexedDb 中数据还是分为主键 id 和数据主体两个部分,并不会像 MYSQL 中在 Table 中呈现四列 。
- 向数据库中添加数据
// 这里的 db 就是第二步中的 db 对象,// transaction api 的第一个参数是数据库名称,第二个参数是操作类型let newItem = { id: 1, name: '徐嘻嘻', age: 3, sex: 'female'};let transaction = db.transaction('dataBaseName', "readwrite");// 找到对应的存储对象let objectStore = transaction.objectStore('person');// 添加到数据对象中, 传入JAVAscript对象objectStore.add(newItem);
- 新建操作是在新建了一个 事务( IDBTransaction 对象)的前提下完成的,传入的数据不需要做任何转换,可以无缝传入 JavaScript 对象 。
- 修改数据库中的数据
// 这里的 db 就是第二步中的 db 对象,// 新建事务let transaction = db.transaction('dataBaseName', "readwrite");// 新数据主体let newRecord = { id: 1, name: '徐嘎嘎', age: 5, sex: 'male'};// 打开已经存储的数据对象let objectStore = transaction.objectStore('person');// 获取存储的对应键的存储对象, 传入主键 id,值为 1 let objectStoreRequest = objectStore.get(1);// 获取成功后替换当前数据objectStoreRequest.onsuccess = function(event) { // 数据 var record = objectStoreRequest.result; // 遍历替换 for (let key in newRecord) { if (typeof record[key] != 'undefined' || key !== 'id') { record[key] = newRecord[key]; } } // 更新数据库存储数据objectStore.put(record);};
推荐阅读
-
初始农人|制作香菇培养料,必须做好2控制3配合,木屑为主料
-
-
-
【问董秘|投资者提问:请问在大数据中心、5G基站等新基建建设中会用到转换器和墙壁开关...】
-
芝麻游戏资讯■《梦幻西游》手游:双龙阵容为何突然跌落神坛?
-
足球部落国际版|最快明天完成体检,尤文核心已启程与巴萨谈判!双方仅存细节问题
-
AuroraGirl|white x Dunk SB 奇奇怪怪,没人喜爱?,Off
-
菊姐说八卦|“流量神话”成过去时,“看脸”吃饭向以艺立身转型
-
DNF心情咖啡屋|DNF:黑一阿旭又起节奏?拿了别人矛盾材料,却声称没有收到
-
【舰载武器杂志】大批米28对叛军武装清场,不等了!俄罗斯深夜发动无差别轰炸
-
佛说:伤害你的人是来度你的,碰到小人,默念这三句话,放过他
-
[顶级豪华车]迈凯轮通过直播发布新型迈凯轮超级跑车
-
「新华网客户端」境外媒体:扬言再次对华加征关税 白宫挑衅言论“吓坏”华尔街
-
养成良好的职业道德的方法 养成良好的职业道德的方法包括
-
晨娱秀场|| 500家影院喜“营业”首日战绩如何?这个电影最受欢迎,数据
-
-
北京:丰台新村街道降为低风险地区 全市仍有2个中风险地区
-
辰龙军事|如今又来买国产战车,比巴铁还铁的哥们出现?买完中国卫星买战舰
-
男生啥时候刮胡子比较好,或者说在嘴部胡子发育到啥程度再进行清理比较好
-
依依畅聊情感故事|衣服故意穿小一码,大秀好身材,李小璐又开始“作妖”