
本文详解如何使用 Laravel Eloquent 的 updateOrCreate() 方法,一行代码安全、原子化地完成记录的条件性更新或插入,避免手动判断和重复查询,提升代码健壮性与可维护性。
本文详解如何使用 laravel eloquent 的 `updateorcreate()` 方法,一行代码安全、原子化地完成记录的条件性更新或插入,避免手动判断和重复查询,提升代码健壮性与可维护性。
在 Laravel 开发中,经常需要根据唯一条件(如 account_id 和 screen_type 组合)来「更新已有记录,或创建新记录」。若沿用原始写法——先 where()->update(),再额外判断是否影响行数、进而执行 create()——不仅逻辑冗长,还存在竞态风险(如两次请求同时判定记录不存在,导致重复插入)。
Eloquent 提供了优雅且线程安全的解决方案:updateOrCreate() 方法。它接收两个参数:
-
第一参数(查找条件):关联数组,定义用于定位记录的唯一字段(如
['account_id' => $account_id, 'screen_type' => 'ctv']); - 第二参数(更新/创建字段):关联数组,指定需写入或更新的字段值(不包含查找条件字段)。
✅ 示例:为不同 screen_type 类型批量处理账户配置
// 自动处理 CTV 类型配置
AccountID::updateOrCreate(
['account_id' => $account_id, 'screen_type' => 'ctv'],
$update_account_ctv // 如 ['status' => 1, 'updated_at' => now()]
);
// 自动处理 APP 类型配置
AccountID::updateOrCreate(
['account_id' => $account_id, 'screen_type' => 'app'],
$update_account_app
);
// 自动处理 SITE 类型配置
AccountID::updateOrCreate(
['account_id' => $account_id, 'screen_type' => 'site'],
$update_account_site
);
⚠️ 注意事项:
-
updateOrCreate()依赖数据库唯一约束(如联合唯一索引UNIQUE(account_id, screen_type))才能保证数据一致性;请务必在迁移中添加:Schema::table('account_ids', function (Blueprint $table) { $table->unique(['account_id', 'screen_type']); }); - 若未设置唯一约束,
updateOrCreate()在查找失败时仍会尝试INSERT,但可能因违反主键/唯一规则而抛出异常; - 该方法内部使用
firstOrNew()+save(),本质是原子操作(非单条 SQL),但在绝大多数场景下已足够高效;如需更高性能且支持 MySQL 8.0+,可考虑upsert()(支持批量、真正单 SQL); - 字段名需严格匹配模型
$fillable或$guarded配置,否则将被忽略。
? 小结:相比手动 update() + 条件 create(),updateOrCreate() 更简洁、语义清晰、天然规避竞态问题,是 Laravel 官方推荐的标准模式。掌握它,让你的数据写入逻辑更专业、更可靠。











