IndexedDB的兼容性问题对于2023年来说,已经不是什么大问题了。作为浏览器缓存武器库的强大一员,它的存储容量大(可达250m以上,根据设备性能适应)、异步读取速度快等特点让其独具魅力。是时候了。。
1、localStorage最大只能存5m,超出5M你就得考虑IndexedDB。
2、地图、低代码等大型平台为了提高性能去缓存大量的数据。
3、用户个性化数据的存储,例如B端系统表格根据个人勾选的个性显示列信息,往往表格很多,此类个性化信息也比较多。
class IndexedDB {
constructor(databaseName, version = 1) {
this.databaseName = databaseName;
this.version = version;
this.db = null;
}
/**
* 打开数据库
*/
open(tableName) {
return new Promise((resolve, reject) => {
this.tableName = tableName
const request = window.indexedDB.open(this.databaseName, this.version);
request.onerror = () => {
reject(new Error(`IndexedDB操作:打开数据库 ${this.databaseName} 失败`));
};
request.onsuccess = () => {
this.db = request.result;
resolve();
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建数据表
const objectStore = db.createObjectStore(tableName, { keyPath: 'dbKey' });
// 添加索引
// objectStore.createIndex('name', 'name', { unique: false });
};
});
}
/**
* 关闭数据库连接
*/
close() {
if (this.db) {
this.db.close();
this.db = null;
}
}
/**
* 获取数据表
* @param {string} tableName - 数据表名称
*/
getObjectStore(tableName) {
const transaction = this.db.transaction(tableName, 'readwrite');
return transaction.objectStore(tableName);
}
/**
* 添加数据
* @param {string} tableName - 数据表名称
* @param {object} data - 要添加的数据对象
*/
async addData(data,tableName= this.tableName) {
const objectStore = this.getObjectStore(tableName);
return new Promise((resolve, reject) => {
const request = objectStore.add(data);
request.onerror = () => {
reject(new Error(`IndexedDB操作:往 ${tableName} 添加数据失败`));
};
request.onsuccess = () => {
resolve(request.result);
};
});
}
/**
* 更新数据
* @param {string} tableName - 数据表名称
* @param {object} data - 要更新的数据对象
*/
async updateData(data,tableName= this.tableName) {
const objectStore = this.getObjectStore(tableName);
return new Promise((resolve, reject) => {
const request = objectStore.put(data);
request.onerror = () => {
reject(new Error(`IndexedDB操作:更新 ${tableName} 数据失败`));
};
request.onsuccess = () => {
resolve(request.result);
};
});
}
/**
* 删除数据
* @param {string} tableName - 数据表名称
* @param {number} dbKey - 要删除的数据 ID
*/
async deleteData(tableName, dbKey) {
const objectStore = this.getObjectStore(tableName);
return new Promise((resolve, reject) => {
const request = objectStore.delete(dbKey);
request.onerror = () => {
reject(new Error(`IndexedDB操作:从 ${tableName} 删除数据失败`));
};
request.onsuccess = () => {
resolve(request.result);
};
});
}
/**
* 查询数据
* @param {string} tableName - 数据表名称
* @param {number} dbKey - 要查询的数据 ID
*/
async getItem(dbKey,tableName = this.tableName) {
const objectStore = this.getObjectStore(tableName);
return new Promise((resolve, reject) => {
const request = objectStore.get(dbKey);
request.onerror = () => {
reject(new Error(`IndexedDB操作:从 ${tableName} 获取数据失败`));
};
request.onsuccess = () => {
resolve(request.result);
};
});
}
/**
* 查询所有数据
* @param {string} tableName - 数据表名称
*/
async getAllData(tableName) {
const objectStore = this.getObjectStore(tableName);
const result = [];
return new Promise((resolve, reject) => {
const request = objectStore.openCursor();
request.onerror = () => {
reject(new Error(`IndexedDB操作:从 ${tableName} 获取数据失败`));
};
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
result.push(cursor.value);
cursor.continue();
} else {
resolve(result);
}
};
});
}
async setItem(dbKey,data,tableName=this.tableName){
const oldData = await this.getItem(dbKey,tableName)
if(oldData){
this.updateData({...data,'dbKey':dbKey},tableName)
}else{
this.addData({...data,'dbKey':dbKey},tableName)
}
}
}
// 使用示例:
async function initDatabase(dbKey) {
window.db = new IndexedDB('yj');
await db.open('yjBaseTable')
}
initDatabase();
setTimeout(() => {
db.getItem('test1').then(res=>{
console.log(res)
})
db.setItem('uuu',{a:1,b:444})
}, 1000);
上面代码是chatGTP3.5生成的,我小改动了一下,不得不说,时代真的是变了。拥抱AI吧。
IndexedDB 中文教程:https://www.tangshuang.net/3735.html#title-9-3-6