You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Laravel Eloquent实现数据库记录的更新或新增(不存在则创建)

解决Laravel Eloquent「有则更新,无则创建」的需求

嘿,刚接触Eloquent的话,你这个需求其实用Laravel内置的两个方法就能轻松搞定——updateOrCreate或者upsert,完美适配这种「目标记录存在就更新,不存在就新增」的场景~

方法一:用updateOrCreate替换原有update语句

这个方法最贴合你现有代码结构,直接把每一行的update换成updateOrCreate就行,逻辑清晰易懂:

// 处理ctv类型的记录
AccountID::updateOrCreate(
    // 第一个参数:查询条件,用来判断记录是否存在
    ['account_id' => $account_id, 'screen_type' => 'ctv'],
    // 第二个参数:要更新/创建的字段数据
    $update_account_ctv
);

// 处理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会先根据第一个数组的条件查询数据库:

  • 如果找到匹配的记录,就用第二个数组的内容更新它;
  • 如果没找到,就把两个数组的字段合并,创建一条新记录。

这个方法不需要额外操作数据库索引,直接就能用,非常适合你这种分类型单独处理的场景。

方法二:用upsert批量处理(更高效)

如果你想一次性完成三个类型的操作,可以用upsert方法,它能批量处理「更新或创建」,减少数据库查询次数,效率更高:

// 先把三个类型的记录整理成一个数组
$records = [
    // 合并查询条件和要更新的数据
    array_merge(['account_id' => $account_id, 'screen_type' => 'ctv'], $update_account_ctv),
    array_merge(['account_id' => $account_id, 'screen_type' => 'app'], $update_account_app),
    array_merge(['account_id' => $account_id, 'screen_type' => 'site'], $update_account_site),
];

// 执行批量upsert
AccountID::upsert(
    $records,
    // 第一个参数:用来判断记录唯一性的字段(必须是数据库里的唯一索引)
    ['account_id', 'screen_type'],
    // 第二个参数:需要更新的字段(如果留空,默认更新所有非唯一性字段)
    array_keys($update_account_ctv) // 假设三个update数组的字段一致,不一致的话可以合并所有键
);

注意事项

用upsert的话,必须在你的account_id数据表上给account_id和screen_type这两个字段建立联合唯一索引,不然Laravel无法判断是否存在冲突记录,会直接抛出错误。

你可以通过迁移文件添加索引:

Schema::table('account_id', function (Blueprint $table) {
    $table->unique(['account_id', 'screen_type']);
});

内容的提问来源于stack exchange,提问作者Bastian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:02:29