共计 3852 个字符,预计需要花费 10 分钟才能阅读完成。
概述
IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。然而不同的是它使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象的数据库。现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过 4KB,且每次请求都会发送回服务器 LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引。所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景
简单来说,IndexedDB 就是浏览器提供的本地数据库。
IndexedDB 具有以下特点
键值对储存
异步操作(避免锁死浏览器)
支持事务
同源限制(协议 + 域名 + 端口)
存储空间大
支持二进制存储(ArrayBuffer 对象和 Blob 对象,可存储文件数据)
基本概念
对比关系数据库 MySql 可以得到以下关系
数据库:IDBDatabase
表格:对象仓库(IDBObjectStore)
行数据:对象仓库存储的一条数据
索引:IDBindex,加速数据的检索(在对象仓库里面可为不同的键创建)
事务:IDBTransaction
操作请求:IDBRequest
IDBCursor:遍历对象存储空间和索引
IDBKeyRange:定义键的范围数据
基本操作
兼容性注意点
// 全局变量兼容性问题
window.indexedDB =
window.indexedDB ||
window.mozIndexedDB ||
window.webkitIndexedDB ||
window.msIndexedDB;
window.IDBTransaction =
window.IDBTransaction ||
window.webkitIDBTransaction ||
window.msIDBTransaction;
window.IDBKeyRange =
window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
if (!window.indexedDB) {
window.alert(
“Your browser doesn’t support a stable version of IndexedDB. Such and such feature will not be available.”
);
}
数据库操作
打开 / 新建数据库
var databaseName = “MyTestDatabase”;
var databaseVersion = 1;
// 打开数据库
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log(“open success”);
};
request.onerror = function(event) {
console.log(“open fail”);
};
request.onupgradeneeded = function(event) {};
window.indexedDB.open 函数打开对应的数据库,如果没有该数据库就会新建。
新建数据库或者数据库版本大于当前版本会触发 onupgradeneeded 事件
数据库为什么会有版本?因为数据库的数据解构可能会发生改变的,所以一般修改数据解构的操作在 onupgradeneeded 里面书写
删除数据库
window.indexedDB.deleteDatabase(databaseName);
对象仓库操作(表格操作)
创建和修改表格是修改数据库的数据解构,所以我把他们写在 onupgradeneeded 事件里
创建表格
request.onupgradeneeded = function(event) {
console.log(“onupgradeneeded”);
db = event.target.result;
// 创建仓库对象(创建表格)
// 这里我将主键设置为 id
var objectStore = db.createObjectStore(objectStoreName, {
keyPath: “id”,
autoIncrement: true
});
};
删除表格
request.onupgradeneeded = function(event) {
console.log(“onupgradeneeded”);
db = event.target.result;
// 删除仓库对象(删除表格)
db.deleteObjectStore(objectStoreName);
};
数据操作(行数据操作)
新增数据(增)
var databaseName = “MyTestDatabase”;
var databaseVersion = 1;
var db;
var objectStoreName = “objectStore1”;
var storeDatas = [
{id: “1”, name: “ 张三 ”, age: 18},
{id: “2”, name: “ 李四 ”, age: 19}
];
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log(“open success”);
db = event.target.result;
// 将数据保存到新建的对象仓库
var objectStore = db
.transaction([objectStoreName], “readwrite”)
.objectStore(objectStoreName);
storeDatas.forEach(function(dataItem) {
// 添加一条数据
objectStore.add(dataItem);
});
};
删除数据(删)
var databaseName = “MyTestDatabase”;
var databaseVersion = 1;
var db;
var objectStoreName = “objectStore1”;
var storeDatas = [
{id: “1”, name: “ 张三 ”, age: 18},
{id: “2”, name: “ 李四 ”, age: 19}
];
var request = window.indexedDB.open(databaseName, databaseVersion);
request.onsuccess = function(event) {
console.log(“open success”);
db = event.target.result;
console.log(“ 删除数据 ”);
var req = db
.transaction([objectStoreName], “readwrite”)
.objectStore(objectStoreName)
.delete(“2”); // 这里的“2”指定的是主键的键值
req.onsuccess = function() {
console.log(“ 删除成功 ”);
};
req.onerror = function() {
console.log(“ 删除失败 ”);
};
};
修改数据(改)
console.log(“ 更新数据 ”);
var req = db
.transaction([objectStoreName], “readwrite”)
.objectStore(objectStoreName)
.put({
id: “2”,
name: “ 王五 ”,
age: 17
}); // 将整条数据给替换
req.onsuccess = function() {
console.log(“ 更新成功 ”);
};
req.onerror = function() {
console.log(“ 更新失败 ”);
};
获取数据(查)
console.log(“ 读取数据 ”);
var req = db
.transaction([objectStoreName], “readonly”)
.objectStore(objectStoreName)
.get(“1”); // 这里的“1”也是主键的键值
req.onsuccess = function() {
console.log(“ 获取成功 ”);
console.log(req.result);
};
req.onerror = function() {
console.log(“ 获取失败 ”);
};
通过指针对象遍历表格数据
console.log(“ 遍历数据 ”);
var objectStore = db
.transaction([objectStoreName], “readonly”)
.objectStore(objectStoreName);
var count = 0;
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
console.log(` 第 ${++count} 条数据为 `);
console.log(cursor.value);
cursor.continue(); // 将指针移动下一个位置
} else {
console.log(“ 没有更多数据 ”);
}
};
小结
indexedDB 的 API 还是非常多的,这里只是简单介绍了最常用的几个操作(个人认为 ^_^)。
参考文档
IndexedDB_API
浏览器数据库 IndexedDB 入门教程