indexedDB
特点
**容量大:**不同浏览器不一样,250MB+
**遵守同源策略:**只能访问同源下的数据库,不能跨域
**异步操作:**防止阻塞(特别是大量数据的操作)
事务支持:确保数据的完整性和一致性
**失效时间:**除非被清理,否则一直存在
键值对存储:不能重复
基本语法
创建数据库
const request = window.indexedDB.open(databaseName,version)
创建或打开一个数据库;如果本地有这个数据库,则直接将这个数据库返回,没有则会先创建,再返回
参数 | 类型 | 说明 |
---|---|---|
databaseName | 字符串 | 数据库名称,必传 |
version | 整数,默认值是1 | 版本号,可选参数,不传则是1 |
返回一个数据库对象IDBOpenDBRequest,我们可以监听这个对象的success和error事件来执行相应操作
request.addEventListener("success", (e) => {
console.log("成功创建或打开数据库", e);
});
request.addEventListener("error", (e) => {
console.log("创建或打开失败");
});
request.addEventListener("upgradeneeded", (e) => {
console.log("升级成功", e);
});
upgradeneeded
事件只会在版本号更新的时候触发,第一次创建也会执行,也是一次版本更新
创建对象仓库
createObjectStore(storeName,data)
createObjectStore()
方法创建了一个对象仓库,第一个参数是对象仓库的名字,在同一数据库中,仓库名不能重复.第二个是可选参数.用于指定数据的主键,以及是否自增主键.
const db = e.target.result;
db.createObjectStore("users", { keyPath: "username" });
创建事务
创建了对象存储之后,剩下的所有操作都是通过“事务”完成的
目的:
- 数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
- 多个应用访问数据库时,提供一个隔离方法,防止彼此的操作互相干扰
创建事务
db.transaction(range,permission)
不传参数则时对所有的对象有只读权限
参数 | 说明 | 详情 |
---|---|---|
range | 访问范围,可选参数 | 事务期间需要访问哪些对象存储的信息,字符串或数组 |
permission | 访问模式,可选参数 | ‘readonly’,‘readwrite’,'versionchange’三选一 |
let transaction = db.transaction("users", "readwrite");
操作数据
添加数据
add(obj) : 增加数据。obj为需要保存到对象仓库中的对象
增加或修改数据
put(obj) : 增加或修改数据
add和put的区别时再添加一个已经存在的同名的键时,add会导致错误,put则会更新该对象
获取数据
get(key) : 获取数据;key为要获取数据的主键值
删除数据
delete(key) : 删除数据
获取所有数据
getAll()
使用游标遍历数据
openCursor()
浏览器中存储说明:
# | Key | Primary Key | Value |
---|---|---|---|
索引列 | 只是用于优化查询, | 主键列,具有唯一性 | 值 |
从建立数据库到操作的基本代码:
// 打开/建立一个数据库
const request = indexedDB.open("myIDB", 1);
let db = null;
request.onerror = function (e) {
console.error("数据库打开失败:", e.target.error);
};
request.onsuccess = function (e) {
console.log("数据库打开成功");
db = e.target.result;
// 注意:获取数据需要等待添加完成,实际使用中可能需要Promise或回调
};
// 数据库升级/初始化
request.onupgradeneeded = function (e) {
db = e.target.result;
// 检查对象存储是否已存在
if (!db.objectStoreNames.contains("customers")) {
const objectStore = db.createObjectStore("customers", {
keyPath: "id",
autoIncrement: true,
});
objectStore.createIndex("name", "name", { unique: false }); // unique属性是不是唯一的
objectStore.createIndex("age", "age", { unique: false });
}
};
const addData = (data) => {
if (!db) {
console.error("数据库未初始化");
return;
}
const transaction = db.transaction("customers", "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.add(data);
request.onsuccess = function () {
console.log("数据添加成功, ID:", request.result); // add操作会返回生成的ID
};
request.onerror = function (event) {
console.error("添加数据失败:", event.target.error);
};
};
const getData = (id) => {
if (!db) {
console.error("数据库未初始化");
return;
}
const transaction = db.transaction("customers");
const objectStore = transaction.objectStore("customers");
const request = objectStore.get(id);
request.onsuccess = function () {
console.log("获取到的数据:", request.result);
};
request.onerror = function (event) {
console.error("获取数据失败:", event.target.error);
};
};
const updateData = (data) => {
if (!db) {
console.error("数据库未初始化");
return;
}
const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.put(data);
request.onsuccess = function () {
console.log("数据已更新");
};
request.onerror = function (event) {
console.error("更新数据失败:", event.target.error);
};
};
const deleteData = (id) => {
if (!db) {
console.error("数据库未初始化");
return;
}
const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.delete(id);
request.onsuccess = function () {
console.log("数据已删除");
};
request.onerror = function (event) {
console.error("删除数据失败:", event.target.error);
};
};
const getAllData = () => {
if (!db) {
console.error("数据库未初始化");
return;
}
const transaction = db.transaction(["customers"], "readwrite");
const objectStore = transaction.objectStore("customers");
const request = objectStore.getAll();
request.onsuccess = function () {
console.log(request.result);
};
request.onerror = function (event) {
console.error("删除数据失败:", event.target.error);
};
};
// 使用游标遍历数据
const iterateCustomers = () => {
const transaction = db.transaction(["customers"]);
const objectStore = transaction.objectStore("customers");
const request = objectStore.openCursor();
request.onsuccess = function (event) {
const cursor = event.target.result;
if (cursor) {
console.log("当前数据:", cursor.value);
cursor.continue(); // 移动到下一条记录
} else {
console.log("遍历结束");
}
};
};
创建索引
createIndex()
createIndex(name: string, keyPath: string | string[], optionalParameters?)
第一个参数name
是索引名,不能重复
第二个参数keyPath
是你要在存储对象上的那个属性上建立索引,可以是一个单个的key值,也可以是一个包含key值集合的数组.
第三个参数optionalParameters
是一个可选的对象参数{unique, multiEntry}
- unique: 用来指定索引值是否唯一
- multiEntry: 当第二个参数
keyPath
为一个数组时.如果multiEntry
是true,则会以数组中的每个元素建立一条索引.如果是false,则以整个数组为keyPath
值,添加一条索引.
关闭数据库
const closeDatabase = () => {
db.close();
console.log("数据库已关闭");
};