示例
function initDB(dbName, storeName) {
let db = null
const request = window.indexedDB.open('myDB', 1)
return new Promise((resolve, reject) => {
request.onsuccess = e => {
console.log('数据库打开成功会执行')
db = e.target.result
resolve(db)
}
request.onupgradeneeded = e => {
console.log('数据库创建和更新会执行')
// 建立对象仓库来存储数据
// 1、根据数据的某个字段作为键路径,要求后续数据必须有该字段
db = e.target.result
if (!db.objectStoreNames.contains(storeName)) {
db.createObjectStore(storeName, { keyPath: 'id' })
}
}
request.onerror = error => {
console.log('数据库打开失败会执行', error)
}
})
}
async function aa() {
const db = await initDB('myDB', 'myStore')
const storeName = 'myStore'
// 1、创建事务
const transaction = db.transaction([ storeName ], 'readwrite');
// 2、访问对象仓库
const store = transaction.objectStore(storeName);
// 3、向仓库添加数据
// store.add(data);
return new Promise((resolve, reject) => {
const res = store.get(1742884986798)
console.error('res', res)
store.onsuccess = e => {
console.log('数据添加成功后触发');
resolve(res)
};
transaction.oncomplete = e => {
console.log('所有数据添加完毕后触发');
resolve(res)
};
transaction.onerror = error => {
console.log('数据添加失败后触发');
resolve(res)
};
})
}
aa().then(res => {
console.log('res1', res.result)
})
// const data = {
// id: Date.now(),
// name: '张三',
// age: 18,
// };
封装
class IndexedDBWrapper {
/**
* 构造函数
* @param {string} dbName - 数据库名称
* @param {number} dbVersion - 数据库版本
* @param {Object} storesConfig - 对象存储配置 {storeName: {keyPath, indexes}}
*/
constructor(dbName, dbVersion, storesConfig) {
this.dbName = dbName;
this.dbVersion = dbVersion;
this.storesConfig = storesConfig;
this.db = null;
}
/**
* 打开数据库连接
* @returns {Promise<IDBDatabase>}
*/
openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, this.dbVersion);
request.onerror = (event) => {
reject(`数据库打开失败: ${event.target.error}`);
};
request.onsuccess = (event) => {
this.db = event.target.result;
resolve(this.db);
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 创建或升级对象存储
for (const storeName in this.storesConfig) {
if (!db.objectStoreNames.contains(storeName)) {
const { keyPath, autoIncrement } = this.storesConfig[storeName];
const store = db.createObjectStore(storeName, {
keyPath,
autoIncrement: autoIncrement || false
});
// 创建索引
if (this.storesConfig[storeName].indexes) {
for (const index of this.storesConfig[storeName].indexes) {
store.createIndex(index.name, index.keyPath, index.options || {});
}
}
}
}
};
});
}
/**
* 添加数据
* @param {string} storeName - 对象存储名称
* @param {Object} data - 要添加的数据
* @returns {Promise<IDBRequest>}
*/
add(storeName, data) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.add(data);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`添加数据失败: ${event.target.error}`);
});
}
/**
* 更新数据
* @param {string} storeName - 对象存储名称
* @param {Object} data - 要更新的数据
* @returns {Promise<IDBRequest>}
*/
put(storeName, data) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.put(data);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`更新数据失败: ${event.target.error}`);
});
}
/**
* 获取数据
* @param {string} storeName - 对象存储名称
* @param {*} key - 主键值
* @returns {Promise<Object>}
*/
get(storeName, key) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readonly');
const store = transaction.objectStore(storeName);
const request = store.get(key);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`获取数据失败: ${event.target.error}`);
});
}
/**
* 获取所有数据
* @param {string} storeName - 对象存储名称
* @returns {Promise<Array>}
*/
getAll(storeName) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readonly');
const store = transaction.objectStore(storeName);
const request = store.getAll();
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`获取所有数据失败: ${event.target.error}`);
});
}
/**
* 删除数据
* @param {string} storeName - 对象存储名称
* @param {*} key - 主键值
* @returns {Promise<IDBRequest>}
*/
delete(storeName, key) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.delete(key);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`删除数据失败: ${event.target.error}`);
});
}
/**
* 清空对象存储
* @param {string} storeName - 对象存储名称
* @returns {Promise<IDBRequest>}
*/
clear(storeName) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.clear();
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`清空存储失败: ${event.target.error}`);
});
}
/**
* 通过索引查询数据
* @param {string} storeName - 对象存储名称
* @param {string} indexName - 索引名称
* @param {*} key - 索引键值
* @returns {Promise<Array>}
*/
getByIndex(storeName, indexName, key) {
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([storeName], 'readonly');
const store = transaction.objectStore(storeName);
const index = store.index(indexName);
const request = index.getAll(key);
request.onsuccess = () => resolve(request.result);
request.onerror = (event) => reject(`索引查询失败: ${event.target.error}`);
});
}
/**
* 关闭数据库连接
*/
close() {
if (this.db) {
this.db.close();
this.db = null;
}
}
/**
* 删除数据库
* @returns {Promise<void>}
*/
deleteDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.deleteDatabase(this.dbName);
request.onsuccess = () => resolve();
request.onerror = (event) => reject(`删除数据库失败: ${event.target.error}`);
request.onblocked = () => reject('数据库被占用,无法删除');
});
}
}
使用示例:
// 配置数据库
const dbConfig = {
dbName: 'MyDatabase',
dbVersion: 1,
storesConfig: {
users: {
keyPath: 'id',
autoIncrement: true,
indexes: [
{ name: 'nameIdx', keyPath: 'name' },
{ name: 'ageIdx', keyPath: 'age' }
]
},
products: {
keyPath: 'productId',
indexes: [
{ name: 'categoryIdx', keyPath: 'category' }
]
}
}
};
// 创建实例
const db = new IndexedDBWrapper(
dbConfig.dbName,
dbConfig.dbVersion,
dbConfig.storesConfig
);
// 使用示例
async function exampleUsage() {
try {
// 打开数据库
await db.openDatabase();
// 添加数据
await db.add('users', { name: 'Alice', age: 25 });
await db.add('users', { name: 'Bob', age: 30 });
// 获取数据
const user = await db.get('users', 1);
console.log('User with id 1:', user);
// 获取所有用户
const allUsers = await db.getAll('users');
console.log('All users:', allUsers);
// 通过索引查询
const usersByName = await db.getByIndex('users', 'nameIdx', 'Alice');
console.log('Users named Alice:', usersByName);
// 更新数据
await db.put('users', { id: 1, name: 'Alice Smith', age: 26 });
// 删除数据
await db.delete('users', 2);
} catch (error) {
console.error('Error:', error);
} finally {
// 关闭连接
db.close();
}
}
exampleUsage();