Laravel中的大规模上流(口才)

时间:2019-04-07 11:57:04

标签: laravel eloquent

是否可以在Laravel(MySQL数据库)中批量追加记录(如果存在,则插入或更新)?

说我有一张桌子,

[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]

4 个答案:

答案 0 :(得分:3)

现在,Laravel具有本机upsert支持。 https://github.com/laravel/framework/pull/34698

Model::upsert([
    ['id' => 1, 'value' => 100],
    ['id' => 3, 'value' => 20],
], 'id');

答案 1 :(得分:1)

好的,您可以使用updateOrCreate()方法。引用documentation

  

您可能还会遇到想要更新现有模型或创建新模型(如果不存在)的情况。 Laravel提供了一个updateOrCreate方法,只需一步即可完成。

$data = collect([
    ['id' => 1, 'value' => 100],
    ['id' => 3, 'value' => 20]
]);

$data->each(function ($item) {
    Model::updateOrCreate([
        ['id' => $item['id']],
        ['value' => $item['value']]
    ]);
});

注意:如果您一次要在数据库中创建/更新一个模型,则这种方法可能导致一次处理很多记录,可能会导致处理速度变慢。

更新#1:减少查询

然后,您可以使用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 在注释中建议的软件包。

答案 2 :(得分:1)

Laravel不支持UPSERT。

我为此创建了一个包:https://github.com/staudenmeir/laravel-upsert

Model::upsert([
    ['id' => 1, 'value' => 100],
    ['id' => 3, 'value' => 20],
], 'id', ['value']);

答案 3 :(得分:1)

Laravel 8 现在有一个 upsert 函数,我在上一个项目中使用了它。我很享受!

https://laravel.com/docs/8.x/queries#update-statements

upsert 方法将插入不存在的记录,并使用您可以指定的新值更新已经存在的记录。该方法的第一个参数包含要插入或更新的值,而第二个参数列出唯一标识关联表中记录的列。该方法的第三个也是最后一个参数是一个列数组,如果数据库中已存在匹配的记录,则应更新该数组:

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