laravel Eloquent模型批量更新

ezykj2lf  于 2023-01-10  发布在  其他
关注(0)|答案(9)|浏览(343)

如果我错了,请纠正我,但我认为在一个雄辩的模型中没有批量更新这样的事情。
有没有一种方法可以在不对每一行发出查询的情况下对DB表进行批量更新?
例如,是否有静态方法,类似于

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

(yes,这是一个愚蠢的例子,但你明白了...)
为什么没有实现这样的功能?如果出现这样的功能,我是唯一一个会很高兴的人吗?
我(开发人员)不想像这样实现它:

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

因为随着项目的增长,我们可能会要求程序员在将来更改表名,而他们无法搜索和替换表名!
是否有这样的静态方法来执行此操作?如果没有,我们是否可以扩展Illuminate\Database\Eloquent\Model类来完成此操作?

ifmq2ha2

ifmq2ha21#

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

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

值得注意的是,在调用update之前需要where方法。

p1iqtdky

p1iqtdky2#

对于批量更新/插入功能,它被要求使用,但Taylor Otwell(Laravel作者)建议用户应该使用Query Builder。https://github.com/laravel/framework/issues/1295
您的模型通常应该扩展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 ...
    • 更新#2**

您必须求助于查询生成器。为了解决表命名问题,您可以通过getTable()方法动态获取它。唯一的限制是您需要在使用此函数之前初始化您的用户类。您的查询如下所示:

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

这样,您的表名在用户模型中就是controller(如上面的示例所示)。

    • 更新#1**

另一种方法(在您的情况下效率不高)是:

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

这样,表名就保留在用户类中,开发人员就不必担心了。

6mzjoqzu

6mzjoqzu3#

对@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();

现在,您可以在一个DB事务中进行一百万次不同的更新

rxztt3cl

rxztt3cl4#

如果您需要更新所有数据而不带任何条件,请尝试以下代码

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

slmsl1lt5#

使用数据库事务批量更新多个实体。事务将在更新函数完成时提交,或在其间发生异常时回滚。
https://laravel.com/docs/5.4/database#database-transactions
例如,下面是我如何在单个批量更新中为项目重新生成物化路径块(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,
                    ]);
            }
        });
    }
ua4mk5z4

ua4mk5z46#

拉腊维尔6号*

我们可以更新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]);
bwleehnv

bwleehnv7#

同一指令中的批量查询和批量更新的工作代码的另一个示例:

Coordinate::whereIn('id',$someCoordIdsArray)->where('status','<>',Order::$ROUTE_OPTIMIZED)
       ->update(['status'=>Order::$ROUTE_OPTIMIZED]);
pbgvytdp

pbgvytdp8#

在Laravel 8中,您还可以使用upsert,它帮助我一次更新多行,每行具有不同的值。
https://laravel.com/docs/8.x/eloquent#upserts

kgqe7b3p

kgqe7b3p9#

laravel 5.8你可以完成批量更新如下:

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

相关问题