「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
前言
说到数据库,可能大家印象当中都会认为是后端的数据库,其实前端也有数据库,只不过前端需要存储的数据量不会有那么多,正常情况下 cookie、localStorage 等等方案已经足够用了,所以前端本地数据库用的会比较少,今天我们就学习一下 indexedDB 的使用
介绍
IndexedDB 是一种底层 API,是一个事务型数据库系统,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。该 API 使用索引实现对数据的高性能搜索。对于存储更大量的结构化数据来说使用 IndexedDB 是一个很好的解决方案。
下面我们与 Cookie、sessionStorage、localStorage 进行一个对比
| 标题 | Cookie | sessionStorage | localStorage | indexedDB |
|---|---|---|---|---|
| 存储大小 | 4kb | 2.5MB - 10MB | 2.5MB - 10MB | >250MB |
| 失效时间 | 设置过期时间,到期后清除 或者 关闭浏览器清除 | 关闭浏览器清除 | 永久保存 | 手动更新 |
| 与服务端交互 | 有 | 无 | 无 | 无 |
| 访问策略 | 同源策略 | 同源策略 | 同源也不可互相访问 | 同源策略 |
由上面这张表可以知道,indexedDB 适合大数据量的场景。而且使用 indexedDB 执行的操作是异步执行的,以免阻塞应用程序。
使用
创建或连接数据库
// 打开数据库
const request = window.indexedDB.open("MyTestDatabase");
var db;
// 数据库打开成功回调
request.onsuccess = function (event) {
db = event.target.result; // 数据库对象
console.log("数据库打开成功");
};
// 数据库打开失败的回调
request.onerror = function (event) {
console.log("数据库打开报错");
};
// 数据库有更新时候的回调
request.onupgradeneeded = function (event) {
// 数据库创建或升级的时候会触发
console.log("onupgradeneeded");
db = event.target.result; // 数据库对象
// 建立一个对象仓库来存储我们客户的相关信息,我们选择 ssn 作为键路径(key path)
// 因为 ssn 可以保证是不重复的
var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
// 建立一个索引来通过姓名来搜索客户。名字可能会重复,所以我们不能使用 unique 索引
objectStore.createIndex("name", "name", { unique: false });
// 使用邮箱建立索引,我们向确保客户的邮箱不会重复,所以我们使用 unique 索引
objectStore.createIndex("email", "email", { unique: true });
}
open 请求不会立即打开数据库或者开始一个事务,他是一个异步操作,所以我们需要监听 request.onsuccess 事件,来判断是否打开成功。 indexedDB.open 方法的第二个参数可以传入版本号,版本号不能是浮点数。
增加数据
首先需要通过transaction方法返回一个事务对象,指定表格名称和操作模式("只读"或"读写"),还有仓库对象。
var transaction = db.transaction(["customers"], "readwrite"); // 表
var objectStore = transaction.objectStore("customers"); // 仓库对象
objectStore.add({ ssn: '1', name: '张三', age: 35, email: '张三@company.com' })
这时候就添加了一条数据,我们可以打开开发者工具的 Application - IndexedDB 查看数据库
因为我们创建了两个索引,所以表customers里有name和email
通过主键读取数据
因为刚刚我们设置了 ssn 字段为我们的主键,所以通过 objectStore.get方法,获取到 ssn === 1 的数据
var transaction = db.transaction(['customers'], 'readwrite'); // 事物对象
var objectStore = transaction.objectStore('customers'); // 仓库对象
const request = objectStore.get('1');
request.onerror = function(event) {
// 错误处理!
};
request.onsuccess = function(event) {
console.log(request.result);
};
更新数据
上一步我们获取到数据以后可以继续进行更新数据
var transaction = db.transaction(['customers'], 'readwrite'); // 事物对象
var objectStore = transaction.objectStore('customers'); // 仓库对象
const request = objectStore.get('1');
request.onerror = function(event) {
// 错误处理!
};
request.onsuccess = function(event) {
var data = event.target.result;
// 更新你想修改的数据
data.age = 42;
// 把更新过的对象放回数据库
var requestUpdate = objectStore.put(data);
requestUpdate.onerror = function(event) {
// 错误处理
};
requestUpdate.onsuccess = function(event) {
// 完成,数据已更新!
};
};
通过put 方法进行修改
删除数据
删除数据的操作很简单,
var request = db.transaction(["customers"], "readwrite")
.objectStore("customers")
.delete("444-44-4444");
request.onsuccess = function(event) {
// 删除成功!
};
总结
indexedDB 在一些数据量大的场景中使用 indexedDB 会更加高效。
兼容性