indexDb是什么?
indexDb是除了cookie,localstorage,sessionstroage外的另一种前端存贮方式。
现有前端存贮比较
indexDb特点
- 无大小限制,适用于前端存贮数据较多场景
- 存贮结构以对象仓库形式,可以存入任何类型数据,包括js对象,二进制数据
- 每条数据都有一个独一无二的主键
- indexDb操作是异步的,不会影响用户其他动作,而localstoreage是同步的
- indexDb受同源影响,只能访问自身域名下的
- indexDb默认存贮位置为C:\Users\当 前 的 登 录 用 户\AppData\Local\Google\Chrome\User Data\Default\IndexedDB
indexDb使用
indexDb的增删改查都是通过事务实现的
1判断是否支持indexDb
window.indexedDB = window.indexdeDB || window.mozIndexedDB || window.webkitIndexedDB
if (window.indexedDB) {
console.log('浏览器支持indexedDb')
}
2创建indexDb数据库
open会创建or打开数据库
// 创建or打开数据库 open(数据库名,数据库版本号)
const request = window.indexedDB.c('myDb',1);
let db = null;
let db_tb = null;
// 数据库创建or打开失败
request.onerror = (error) => {
console.log('创建失败',error)
}
// 数据库创建or打开成功
request.onsuccess = (res) => {
console.log('创建成功', res);
db = request.result;
}
3 创建表,主键,索引
一般会在第一次创建数据库或open新版本时创建表
// 数据库升级 首次创建会触发,指定保本号高于当前被持久化的版本号也会触发
equest.onupgradeneeded = (res) => {
console.log('升级成功', res);
db = request.result;
if (!db.objectStoreNames.contains('student')) {
db_tb = db.createObjectStore('student', { keyPath: 'id' }) // 创建表,键的选项,指明主键为id
db_tb.createIndex('indexName','name',{unique: false}) // 创建索引, 索引名,创建索引的列,选项 方便查找
}
}
具体的索引,主键选项
创建完毕的,表,索引,主键,value
4 创建事务
// 创建事务,事务操作的对象存贮空间名(表明),事务模式: readonly 只读,readwrite:可读可写,versionchange: 版本升级
let transaction = mdb.transaction(['student'], 'readwrite');
// 事务操作处理完成时触发
transaction.oncomplete = (res) => {
console.log('执行完毕',res)
}
// 事务操作处理完成时触发
transaction.onerror = (error) => {
console.log('报错',error)
}
// 事务中止后触发
transaction.onabort = (error) => {
console.log('中止',error)
}
5 通过事务进行操作
首先通过事务列表获取具体要操作的事务对象
// 获得某个表的具体事务对象
let store = transaction.objectStore('student');
插入数据
let data = {
id: '111',
name: '李明',
age: 12,
}
const addRes = store.add(data); // 注意id和name 要和声明主键和索引的字段一样
addRes.onsuccess = (res) => {
console.log('插入成功', res)
}
addRes.onerror = (error) => {
console.log('插入失败', error)
}
获取数据
- 通过主键获取
// 获取数据通过主键
const getRes = store.get('111');
getRes.onsuccess = (res) => {
console.log('获取成功', res)
}
getRes.onerror = (error) => {
console.log('获取失败', error)
}
- 通过索引获取
// 获取数据通过索引
const getIdxRes = store.index('indexName').get('李四');
getIdxRes.onsuccess = (res) => {
console.log('获取成功', res)
}
getIdxRes.onerror = (error) => {
console.log('获取失败', error)
}
- 获取所有
// 获取所有
const getAllRes = store.getAll();
getAllRes.onsuccess = (res) => {
console.log('获取成功', res)
}
getAllRes.onerror = (error) => {
console.log('获取失败', error)
}
- 获取指定条件
// 获取指定条件索引
const getReRes = store.getAll(IDBKeyRange.upperBound(+new Date()));
getReRes.onsuccess = (res) => {
console.log('获取成功', res)
}
getReRes.onerror = (error) => {
console.log('获取失败', error)
}
更新数据
// 更新数据
const updateRes = store.put({
id: '111',
name: "李明",
age:10
});
updateRes.onsuccess = (res) => {
console.log('更新成功', res)
}
updateRes.onerror = (error) => {
console.log('更新失败', error)
}
删除数据
// 删除数据通过主键
const deleteRes = store.delete('111');
deleteRes.onsuccess = (res) => {
console.log('获取成功', res)
}
deleteRes.onerror = (error) => {
console.log('获取失败', error)
}
使用的坑
- indexDb异步操作,任何需要使用上一步操作结果都需要在complete,success回调事件之后再调用
- 一个事务开启未执行完毕,不能执行另一个事务,可以在事务onComplete回调中监听上一个事务是否执行完毕
参考文档
https://juejin.cn/post/7239259798267904059
https://blog.csdn.net/qq_36823300/article/details/101382736