indexeddb 的 put 方法自动实现“有则更新、无则插入”语义:根据主键存在与否决定覆盖或新增;支持单条与批量 upsert,但无原生批量 api;按非主键字段 upsert 需结合唯一索引与手动查找。

IndexedDB 的 put 方法本身不区分“插入”还是“更新”,它会根据传入记录的主键(或索引键)自动判断:如果键已存在,就覆盖;不存在,就新增。所以“增量更新与插入”本质上就是用 put 写入一条数据,由数据库自动完成“有则更新、无则插入”的语义。
理解 put 的行为逻辑
put 是 IDBObjectStore 的方法,接受一个对象和可选的主键参数。它的核心规则是:
- 若对象自身含主键(比如主键是
keyPath指定的属性,如id),且该属性值在 store 中已存在 → 执行更新 - 若对象含主键但该值不存在 → 执行插入
- 若未提供主键,且 store 启用了自增主键(
autoIncrement: true),则生成新主键并插入 - 若未提供主键,且 store 不支持自增 → 报错
基础用法:单条记录的 upsert
假设你有一个用户 store,主键为 id,使用 put 实现用户信息的保存(新增或更新):
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
const user = { id: 101, name: '张三', email: 'zhang@example.com' };
const request = store.put(user); // 自动判断:id=101 存在则更新,不存在则插入
request.onsuccess = () => console.log('保存成功');
request.onerror = () => console.error('保存失败:', request.error);
批量 upsert:用 add() 或多次 put?
IndexedDB 本身没有原生的批量 upsert API,但你可以循环调用 put 安全地处理多条记录:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 每条记录独立执行
put,互不影响 - 避免混用
add()(只插入,重复主键报错)和put()(覆盖式),统一用put更稳妥 - 注意事务生命周期:所有
put应在同一个事务内发起,否则可能跨事务冲突
示例:
const users = [
{ id: 101, name: '张三', score: 85 },
{ id: 102, name: '李四', score: 92 }
];
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
users.forEach(user => store.put(user));
transaction.oncomplete = () => console.log('批量保存完成');
transaction.onerror = () => console.error('批量操作失败');
结合 index 实现按非主键字段 upsert
如果想根据邮箱(email)而非 id 判断是否已存在,需配合唯一索引 + 手动查找:
- 先在 store 上创建唯一索引:
store.createIndex('by-email', 'email', { unique: true }) - 用
index.get(email)查是否存在 - 存在则获取原记录并合并更新字段,再
put;不存在则直接put新对象
注意:这不再是原子操作,需处理竞态(如查完到写入之间被其他操作修改),生产环境建议封装成工具函数并加锁或重试逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










