Laravel 8 起新增了一个upsert方法,用来实现批量更新或新增,如果你想在单个查询中执行多个「新增或更新」,那么应该使用 upsert 方法。该方法的第一个参数包含要插入或更新的值,而第二个参数列出了在关联表中唯一标识记录的列。该方法的第三个也是最后一个参数是一个列数组,如果数据库中已经存在匹配的记录,则应该更新这些列。如果在模型上启用了时间戳,upsert 方法将自动设置 created_at 和 updated_at 时间戳:

Flight::upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);

注意
除 SQL Server 外,其他所有数据库都要求 upsert 方法的第二个参数中的列具有主键索引或唯一索引。 此外,MySQL 数据库驱动程序忽略了 upsert 方法的第二个参数,总是使用表的主键索引和唯一索引来检测现有的记录

Laravel 8 之前的版本,如果我们想要批量更新或新增,只能通过循环+updateOrCreate的方式,每次循环都要请求两次数据库,但是有了upsert我们一共只需要执行两次数据库操作。

另外要说明的是,第二个参数数组是用来标识唯一记录的,可以使用主键索引,比如:自增id,也可以使用唯一索引。比如下面的代码:

Record::upsert($data,['user_id','date']);

必须要在数据库上设置 user_id + date 的唯一索引才可以,否则就会不断的执行新增操作。