网站首页 > 技术文章 正文
扫码关注公众号「政采云前端团队」,获取更多不掺水的原创好文~
IndexedDB 是什么
在现代浏览器的本地存储方案中,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 细节日后可以慢慢深入学习。
1、必不可少的浏览器支持检查:
if(!('indexedDB' in window))
{
console.log('当前浏览器支持 IndexedDB');
return;
} else {
console.log('您的浏览器不支持 IndexedDB')
// todo 建议升级或者更换其他浏览器
}
2、连接数据库
// 数据库实例
let db;
// 数据库打开操作,第一个参数是数据库名称, 第二个参数是数据库版本
let DBRequestLink = window.indexedDB.open('dataBaseName', 1)
DBRequestLink.onsuccess = function(event) {
// 获取数据库实例
db = DBRequestLink.result;
// 其他操作
};
// 这个监听回调触发于数据库首次新建、open数据库时传递新版本(只能比之前传递的版本高)
DBRequestLink.onupgradeneeded = function(event) {};
3、创建数据库的主键和字段
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 中呈现四列。
4、向数据库中添加数据
// 这里的 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 对象。
5、修改数据库中的数据
// 这里的 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);
};
基本思路是创建一个事务,先找到想要修改的数据主体,然后在更新该数据主体内容。 事务创建逻辑相同,并在创建之后调用事务的 get 和 put 操作。
6、删除数据库中的数据
// 这里的 db 就是第二步中的 db 对象,
// 新建事务
let transaction = db.transaction('dataBaseName', "readwrite");
// 打开已经存储的数据对象
let objectStore = transaction.objectStore('person');
// 获取存储的对应键的存储对象, 传入主键 id,值为 1
let objectStoreRequest = objectStore.delete(1);
调用 delete 接口,传入指定的 id 即可。
可以提效的类库
? 从上面的例子中可以看出,每一次操作需要至少三行代码才能完成,而且需要一直维护 DB 的对象引用,避免它被回收,这样子开发代码膨胀得太厉害,所以我们在业务中引入其他类库来减少代码量
- LocalForage 可以指定数据存储方案,默认依次为 IndexedDB、WebSQL、LocalStorage,意味着当前 IndexedDB 失效可以有兜底措施。API 简化为 CRUD ( getItem、removeItem、setItem、clear )库大小为 475b
- Pouchdb API 简化为 put、get、remove,基于 promise 来检查回收错误有较好的错误日志机制, 如失败,冲突等等,方便调试库大小为 255b
这两个类库比较符合我们的开发要求,我们当前使用的是 LocalForage。
结束语
在业务开发中,我们都会碰到或多或少的本地存储需求,本文介绍了其中一种存储方案 IndexedDB 的简单实践。就我们的应用场景来看,IndexedDB 的适用面还是很广的。考虑到 IE10 也可以支持,把它实践在实际项目中应该是没有问题的。
文章内容较长,如果表达有误在所难免,欢迎交流指出。
招贤纳士
政采云前端团队(ZooTeam),一个年轻富有激情和创造力的前端团队,隶属于政采云产品研发部,Base 在风景如画的杭州。团队现有 50 余个前端小伙伴,平均年龄 27 岁,近 3 成是全栈工程师,妥妥的青年风暴团。成员构成既有来自于阿里、网易的“老”兵,也有浙大、中科大、杭电等校的应届新人。团队在日常的业务对接之外,还在物料体系、工程平台、搭建平台、性能体验、云端应用、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,持续探索前端技术体系的新边界。
如果你想改变一直被事折腾,希望开始能折腾事;如果你想改变一直被告诫需要多些想法,却无从破局;如果你想改变你有能力去做成那个结果,却不需要你;如果你想改变你想做成的事需要一个团队去支撑,但没你带人的位置;如果你想改变既定的节奏,将会是“5 年工作时间 3 年工作经验”;如果你想改变本来悟性不错,但总是有那一层窗户纸的模糊… 如果你相信相信的力量,相信平凡人能成就非凡事,相信能遇到更好的自己。如果你希望参与到随着业务腾飞的过程,亲手推动一个有着深入的业务理解、完善的技术体系、技术创造价值、影响力外溢的前端团队的成长历程,我觉得我们该聊聊。任何时间,等着你写点什么,发给 ZooTeam@cai-inc.com
猜你喜欢
- 2024-09-29 技术: Java语言,后端:springboot 前端:JSP数据库
- 2024-09-29 「免费开源」基于Vue和Quasar的前端SPA项目实战之数据库逆向
- 2024-09-29 浅谈高性能数据库集群——分库分表
- 2024-09-29 「融职培训」Web前端学习 第9章 教务管理系统开发4 数据库模型
- 2024-09-29 我是如何把微服务的这个模式落地的:一个服务一个数据库模式
- 2024-09-29 JS写的服务端,如何连接Mysql数据库,实现增删查改功能
- 2024-09-29 一文带你搞懂前端本地存储 前端储存方式
- 2024-09-29 TP开发时,后端数据库存储的信息有时候是索引,前端如何显示信息
- 2024-09-29 ios系统 websql前端数据库 值是undefined
- 2024-09-29 Java面试之数据库篇(offer 拿来吧你)
你 发表评论:
欢迎- 05-10如何优化数据库和前端之间的交互?
- 05-10前端代码优化小秘籍(前端优化24条建议)
- 05-10VS Code当中的15个神仙插件,值得收藏
- 05-10如何自己开发一个Google浏览器插件?
- 05-10前端流行框架Vue3教程:14. 组件传递Props效验
- 05-10吃了一年的SU,最好用的插件都在这了
- 05-10前端必看!这款神器让网站界面告别千篇一律
- 05-10程序员请收好:10个非常有用的 Visual Studio Code 插件
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端懒加载 (45)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle查询数据库 (45)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)