Eloquent 模型海量更新

2022-01-08 00:00:00 php laravel laravel-4 eloquent

如果我错了,请纠正我,但我认为 Eloquent 模型中不存在大规模更新.

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

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

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!

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

Is there such a static method to perform this operation? And if there is not, can we extend the IlluminateDatabaseEloquentModel class to accomplish such a thing?

推荐答案

对于大规模更新/插入功能,有人提出了要求,但 Taylor Otwell(Laravel 作者)建议用户应该使用 Query Builder.https://github.com/laravel/framework/issues/1295

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

您的模型通常应该扩展 IlluminateDatabaseEloquentModel.然后你自己访问实体,例如,如果你有这个:

Your models should generally extend IlluminateDatabaseEloquentModel. Then you access the entity iself, for example if you have this:

<?php
Use IlluminateDatabaseEloquentModel;

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 ...

更新 #2

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

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:

$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).

更新 #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.

相关文章