php Eloquent 模型批量更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22430716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:56:01  来源:igfitidea点击:

Eloquent model mass update

phplaravellaravel-4eloquent

提问by papas-source

Please correct me if I am wrong, but I think there is no such thing as mass update in an Eloquent model.

如果我错了,请纠正我,但我认为 Eloquent 模型中没有大规模更新这样的东西。

Is there a way to make a mass update on the DB table without issuing a query for every row?

有没有办法在不为每一行发出查询的情况下对数据库表进行批量更新?

For example, is there a static method, something like

例如,是否有静态方法,例如

User::updateWhere(
    array('age', '<', '18'),
    array(
        'under_18' => 1 
        [, ...]
    )
);

(yes, it is a silly example but you get the picture...)

(是的,这是一个愚蠢的例子,但你得到了图片......)

Why isn't there such a feature implemented? Am I the only one who would be very happy if something like this comes up?

为什么没有实现这样的功能?如果发生这样的事情,我是唯一一个会很高兴的人吗?

I (the developers), wouldn't like to implement it like:

我(开发人员)不想像这样实现它:

DB::table('users')->where('age', '<', '18')->update(array('under_18' => 1));

because as the project grows, we may require the programmers to change the table name in the future and they cannot search and replace for the table name!

因为随着项目的增长,我们以后可能会要求程序员更改表名,而他们无法搜索和替换表名!

Is there such a static method to perform this operation? And if there is not, can we extend the Illuminate\Database\Eloquent\Modelclass to accomplish such a thing?

有没有这样的静态方法来执行这个操作?如果没有,我们可以扩展Illuminate\Database\Eloquent\Model类来完成这样的事情吗?

回答by bryceadams

Perhaps this was not possible a few years ago but in recent versions of Laravel you can definitely do:

也许这在几年前是不可能的,但在 Laravel 的最新版本中,你绝对可以做到:

User::where('age', '<', 18)->update(['under_18' => 1]);

Worth noting that you need the where method before calling update.

值得注意的是,在调用update.

回答by phoops

For mass update/insert features, it was requested but Taylor Otwell (Laravel author) suggest that users should use Query Builder instead. https://github.com/laravel/framework/issues/1295

对于大量更新/插入功能,它被要求但 Taylor Otwell(Laravel 作者)建议用户应该使用 Query Builder。https://github.com/laravel/framework/issues/1295

Your models should generally extend Illuminate\Database\Eloquent\Model. Then you access the entity iself, for example if you have this:

你的模型通常应该扩展 Illuminate\Database\Eloquent\Model。然后你访问实体本身,例如,如果你有这个:

<?php
Use Illuminate\Database\Eloquent\Model;

class User extends Model {

    // table name defaults to "users" anyway, so this definition is only for
    // demonstration on how you can set a custom one
    protected $table = 'users';
    // ... code omited ...

Update #2

更新 #2

You have to resort to query builder. To cover table naming issue, you could get it dynamically via getTable() method. The only limitation of this is that you need your user class initialized before you can use this function. Your query would be as follows:

您必须求助于查询构建器。为了解决表命名问题,您可以通过 getTable() 方法动态获取它。唯一的限制是您需要先初始化用户类,然后才能使用此功能。您的查询如下:

$userTable = (new User())->getTable();
DB::table($userTable)->where('age', '<', 18)->update(array('under_18' => 1));

This way your table name is controller in User model (as shown in the example above).

这样你的表名是用户模型中的控制器(如上例所示)。

Update #1

更新 #1

Other way to do this (not efficient in your situation) would be:

其他方法(在您的情况下效率不高)是:

$users = User::where('age', '<', 18)->get();
foreach ($users as $user) {
    $user->field = value;
    $user->save();
}

This way the table name is kept in users class and your developers don't have to worry about it.

这样表名就保存在用户类中,你的开发人员不必担心它。

回答by catalin87

A litle correction to @metamaker answer:

对@metamaker 的回答稍作修正:

DB::beginTransaction();
     // do all your updates here

        foreach ($users as $user) {

            $new_value = rand(1,10) // use your own criteria

            DB::table('users')
                ->where('id', '=', $user->id)
                ->update([
                    'status' => $new_value  // update your field(s) here
                ]);
        }
    // when done commit
DB::commit();

Now you can have 1 milion different updates in one DB transaction

现在您可以在一个数据库事务中进行 100 万次不同的更新

回答by metamaker

Use database transactions to update multiple entities in a bulk. Transaction will be committed when your update function finished, or rolled back if exception occurred somewhere in between.

使用数据库事务批量更新多个实体。当您的更新功能完成时,事务将被提交,或者如果在两者之间发生异常则回滚。

https://laravel.com/docs/5.4/database#database-transactions

https://laravel.com/docs/5.4/database#database-transactions

For example, this is how I regenerate materialized path slugs (https://communities.bmc.com/docs/DOC-9902) for articles in a single bulk update:

例如,这就是我在单个批量更新中为文章重新生成物化路径 slug ( https://communities.bmc.com/docs/DOC-9902) 的方式:

public function regenerateDescendantsSlugs(Model $parent, $old_parent_slug)
    {
        $children = $parent->where('full_slug', 'like', "%/$old_parent_slug/%")->get();

        \DB::transaction(function () use ($children, $parent, $old_parent_slug) {
            /** @var Model $child */
            foreach ($children as $child) {
                $new_full_slug  = $this->regenerateSlug($parent, $child);
                $new_full_title = $this->regenerateTitle($parent, $child);

                \DB::table($parent->getTable())
                    ->where('full_slug', '=', $child->full_slug)
                    ->update([
                        'full_slug' => $new_full_slug,
                        'full_title' => $new_full_title,
                    ]);
            }
        });
    }

回答by Irfandi D. Vendy

If you need to update all data withoutany condition, try below code

如果您需要无条件更新所有数据,请尝试以下代码

Model::query()->update(['column1' => 0, 'column2' => 'New']);

回答by suryadeep bhujel

Laravel 6.*

Laravel 6.*

We can update mass data on queryas follow :

我们可以更新海量数据query如下:

Appointment::where('request_id' , $appointment_request->id)->where('user_id', Auth::user()->id)->where('status', '!=', 'Canceled')->where('id', '!=', $appointment->id)->update(['status' => 'Canceled', 'canceled_by' => Auth::user()->id]);

回答by Moshood Sikiru

laravel 5.8 you can accomplish mass update like so:

laravel 5.8 你可以像这样完成批量更新:

User::where('id', 24)->update (dataAssociativeArray) ;