是否有办法在Laravel(MySQL数据库)中批量插入(插入或更新,如果存在)记录?假设我有一张table,上面有:
[id:1 value:4] [id:2 value:5]
我想执行:
Model::massupsert([ [id:1 value:100], [id:3 value:20] ]);
之后的表为:
[id:1 value:100] [id:2 value:5] [id:3 value:20]
q9yhzks01#
现在(2020年10月6日),Laravel(v8.10.0)拥有原生upsert支持。https://github.com/laravel/framework/pull/34698
upsert
Model::upsert([ ['id' => 1, 'value' => 100], ['id' => 3, 'value' => 20], ], 'id');
3bygqnnd2#
Laravel没有原生UPSERT支持。我已经为此创建了一个包:https://github.com/staudenmeir/laravel-upsert
Model::upsert([ ['id' => 1, 'value' => 100], ['id' => 3, 'value' => 20], ], 'id', ['value']);
wecizke33#
当然,你可以使用updateOrCreate()方法。引用文档:你也可能遇到这样的情况,你想要更新一个现有的模型或者创建一个新的模型,Laravel提供了一个updateOrCreate方法来一步完成。
updateOrCreate()
$data = collect([ ['id' => 1, 'value' => 100], ['id' => 3, 'value' => 20] ]); $data->each(function ($item) { Model::updateOrCreate([ ['id' => $item['id']], ['value' => $item['value']] ]); });
**注意:**如果您必须一次处理许多记录,则此方法可能会导致处理速度变慢,因为您一次只能在数据库中创建/更新一个模型。
然后,您可以使用firstOrNew稍微减少查询次数,因为您只是将新记录批量插入到数据库中,但目前您必须手动更新已经存在的记录,一次更新一条记录:
firstOrNew
$data = collect([ ['id' => 1, 'value' => 100], ['id' => 3, 'value' => 20] ]); $models = $data->map(function ($attributes) { $model = Model::firstOrCreate([ ['id' => $attributes['id']], ['value' => $attributes['value']] ]); if (! $model->exists) { $model->fill($attributes); } return $model; }); list($saved, $unsaved) = $models->partition(function ($model) { return $model->exists; }); Model::insert($unsaved); $saved->each->update();
目前,要使用单个查询完成此操作,您必须使用 Jonas Staudenmeir 在评论中建议的包。
siv3szwd4#
Laravel 8现在有一个upsert功能,我在上一个项目中使用过。我非常喜欢它!https://laravel.com/docs/8.x/queries#update-statementsupsert方法将插入不存在的记录,并用您指定的新值更新已存在的记录。该方法的第一个参数由要插入或更新的值组成。而第二个参数列出列唯一标识关联表中记录的方法。方法'的第三个也是最后一个参数是一个列数组,如果数据库中已存在匹配记录,则应更新该数组:
DB::table('flights')->upsert([ ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99], ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150] ], ['departure', 'destination'], ['price']);
4条答案
按热度按时间q9yhzks01#
现在(2020年10月6日),Laravel(v8.10.0)拥有原生
upsert
支持。https://github.com/laravel/framework/pull/346983bygqnnd2#
Laravel没有原生UPSERT支持。
我已经为此创建了一个包:https://github.com/staudenmeir/laravel-upsert
wecizke33#
当然,你可以使用
updateOrCreate()
方法。引用文档:你也可能遇到这样的情况,你想要更新一个现有的模型或者创建一个新的模型,Laravel提供了一个updateOrCreate方法来一步完成。
**注意:**如果您必须一次处理许多记录,则此方法可能会导致处理速度变慢,因为您一次只能在数据库中创建/更新一个模型。
更新#1:减少质询
然后,您可以使用
firstOrNew
稍微减少查询次数,因为您只是将新记录批量插入到数据库中,但目前您必须手动更新已经存在的记录,一次更新一条记录:目前,要使用单个查询完成此操作,您必须使用 Jonas Staudenmeir 在评论中建议的包。
siv3szwd4#
Laravel 8现在有一个upsert功能,我在上一个项目中使用过。我非常喜欢它!
https://laravel.com/docs/8.x/queries#update-statements
upsert方法将插入不存在的记录,并用您指定的新值更新已存在的记录。该方法的第一个参数由要插入或更新的值组成。而第二个参数列出列唯一标识关联表中记录的方法。方法'的第三个也是最后一个参数是一个列数组,如果数据库中已存在匹配记录,则应更新该数组: