Skip to content

IndexedDB - 更新数据

一旦你的数据库和对象存储区设置完毕,下一步就是用数据填充它们。IndexedDB 提供了两种主要的数据写入方法:put() 和 add()。所有写入操作都必须在 readwrite 事务中进行。

理解这两种方法之间的区别对于防止数据丢失或意外错误至关重要。

  • objectStore.put(data, [key]):此方法执行“更新或插入”(upsert)。如果存储区中已存在具有相同主键的对象,则它将被新 data 完全替换。如果不存在具有该键的对象,则会创建一个新对象。这是最常用的方法。
  • objectStore.add(data, [key]):此方法仅用于插入。它将新 data 添加到存储区。如果已存在具有相同主键的对象,则操作将失败,并且请求的 error 事件将触发 ConstraintError。当你想要确保不覆盖现有数据时,请使用 add()。

此示例展示了一种常见模式:添加初始数据、检索特定记录、修改它,然后使用 put() 将更改保存回数据库。我们将使用推荐的 idb 库,以实现更简洁、更具可读性的 async/await 语法。

<!DOCTYPE html>
<html lang="en">
<head>
<title>IndexedDB 更新数据示例</title>
<script type="module" src="app.js"></script>
</head>
<body>
<h1>在 IndexedDB 中更新数据</h1>
<p>请检查控制台输出。</p>
</body>
</html>
// app.js
import { openDB } from 'https://cdn.jsdelivr.net/npm/idb@7/build/esm/index.js';
const DB_NAME = 'BotDatabaseV2';
const STORE_NAME = 'bots';
async function dataUpdateDemo() {
const db = await openDB(DB_NAME, 1, {
upgrade(db) {
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: 'id' });
}
},
});
// 1. 使用 add() 添加一些初始数据
console.log('正在添加初始机器人...');
const txAdd = db.transaction(STORE_NAME, 'readwrite');
try {
await Promise.all([
txAdd.store.add({ id: 1, name: 'Jason', branch: 'IT', version: 1 }),
txAdd.store.add({ id: 2, name: 'Praneeth', branch: 'CSE', version: 1 }),
txAdd.store.add({ id: 4, name: 'Abdul', branch: 'IT', version: 1 }),
]);
await txAdd.done;
console.log('初始机器人已添加。');
} catch (error) {
if (error.name === 'ConstraintError') {
console.warn('初始数据已存在。跳过添加。');
// 如果存在约束错误,为安全起见中止事务
txAdd.abort();
} else {
console.error('添加机器人时出错:', error);
}
}
// 2. 使用 put() 读取、修改和更新记录
console.log('\n--- 正在更新机器人 ID 4 ---');
const txUpdate = db.transaction(STORE_NAME, 'readwrite');
// 获取要更新的机器人
const botToUpdate = await txUpdate.store.get(4);
console.log('原始机器人数据:', botToUpdate);
if (botToUpdate) {
// 修改其属性
botToUpdate.name = 'Abdul Rahman';
botToUpdate.version = 2;
// 使用 put() 保存更改
await txUpdate.store.put(botToUpdate);
console.log('机器人已使用 put() 更新。');
}
await txUpdate.done;
// 3. 验证更新
console.log('\n--- 正在验证更新 ---');
const updatedBot = await db.get(STORE_NAME, 4);
console.log('更新后获取的机器人数据:', updatedBot);
db.close();
}
dataUpdateDemo();
  • 忘记使用 put(): 修改从数据库中检索到的 JavaScript 对象不会自动保存。你必须在 readwrite 事务中显式调用 put() 来持久化更改。
  • 对现有数据使用 add(): 使用已存在于对象存储区中的键调用 add() 将抛出 ConstraintError 并中止整个事务。该事务中的任何其他操作都将被回滚。