IndexedDB是一种在浏览器端存储数据的方式,它丰富了客户端的查询方式,由于是本地存储,可以有效减少网络对页面数据的影响。这使得浏览器可以存储更多的数据,从而丰富了浏览器端的应用类型。
IndexedDB与传统的关系型数据库不同,它是一个key-value型的数据库。其中,value可以是复杂的结构体对象,而key可以是对象的某些属性值,也可以是其他的对象(包括二进制对象)。使用对象中的任何属性作为index,可以加快查找速度。此外,IndexedDB是自带transaction的,所有的数据库操作都会绑定到特定的事务上,并且这些事务是自动提交的,IndexedDB并不支持手动提交事务。
IndexedDB是一种NoSQL数据库,面向对象,主要存储的是Javascript对象。而且,IndexedDB的API大部分都是异步的,使用异步方法时,API不会立即返回要查询的数据,而是返回一个callback。
总的来说,IndexedDB为浏览器提供了更强大的数据存储和查询能力,使开发者能够创建更丰富、更复杂的浏览器端应用。
以下是IndexedDB的一个使用案例:
module.exports = {
dbName: 'dbTest',
version: 1,
db: null,
indexedDB: window.indexedDB || window.webkitIndexedDB,
// 异步方法改写,包括错误处理的优化
async openDB() {
try {
const request = this.indexedDB.open(this.dbName, this.version);
// 如果数据库不存在或者版本号更高,触发 onupgradeneeded 事件
request.onupgradeneeded = (event) => {
this.db = event.target.result;
// 确保数据库中已经包含了所有必要的对象存储
['mystore', 'mystore01'].forEach(storeName => {
if (!this.db.objectStoreNames.contains(storeName)) { // 如果没有名为 'mystore' 的对象存储
this.db.createObjectStore(storeName, { keyPath: 'id' }); // 创建新的对象存储,并设置主键为 'id'
}
});
};
request.onsuccess = (event) => {
this.db = event.target.result;
console.log("Database opened successfully", event.target.result);
};
request.onerror = (event) => {
console.error("Error opening IndexedDB:", event.target.errorCode);
};
} catch (error) {
console.error("Error opening IndexedDB asynchronously:", error);
}
},
// 使用Promise替代回调,优化异步处理
async addData(myStore, data) {
try {
const store = this.getStore(myStore);
return new Promise((resolve, reject) => {
const addRequest = store.add(data);
addRequest.onsuccess = (event) => {
console.log('添加成功!', event.target.result);
resolve(event.target.result);
};
addRequest.onerror = (event) => {
console.log('添加失败!', event.target.error);
reject(event.target.error);
};
});
} catch (error) {
console.error("Error adding data:", error.name, error.message);
throw error; // 重新抛出错误,以便调用者可以捕获
}
},
getById(myStore, id) {
return new Promise((resolve, reject) => {
const store = this.getStore(myStore);
const request = store.get(id);
request.onerror = (event) => {
console.error('查询数据失败:', event.target.error);
reject(event.target.error);
};
request.onsuccess = (event) => {
const result = event.target.result;
console.log('查询数据成功:', result);
resolve(result);
};
});
},
// 更新数据方法
updateById(myStore, data) {
return this._handleDatabaseRequest(() => {
const store = this.getStore(myStore);
return store.put(data);
}, '更新数据');
},
// 删除数据方法
deleteById(myStore, id) {
return this._handleDatabaseRequest(() => {
const store = this.getStore(myStore);
return store.delete(id);
}, '删除数据');
},
getStore(myStore) {
if (!this.db) {
this.openDB(); // 确保数据库已经打开
}
if (!this.db.objectStoreNames.contains(myStore)) {
throw new Error(`Object store ${myStore} does not exist.`);
}
const transaction = this.db.transaction(myStore, 'readwrite');
const store = transaction.objectStore(myStore);
return store;
},
// 私有方法,用于处理数据库请求,减少代码重复
_handleDatabaseRequest (operation, actionName) {
try {
return new Promise((resolve, reject) => {
const request = operation();
request.onsuccess = (event) => {
console.log(`${actionName}成功:`, event.target.result);
resolve(event.target.result);
};
request.onerror = (event) => {
console.error(`${actionName}失败:`, event.target.error);
reject(event.target.error);
};
});
} catch (error) {
console.error(`Error during ${actionName}:`, error.name, error.message);
throw error;
}
}
}