如何在批量更新多行时向对应JSON类型字段追加指定数组?
批量追加JSON字段内容实现方案
Laravel 没有内置appendJson方法,但可以通过数据库原生JSON函数配合查询构造器快速实现,也可以自行封装便捷调用方法:
方法1:直接使用原生函数实现(无需额外封装)
根据你使用的数据库选择对应写法即可:
- MySQL 环境写法
Model::whereIn('id', $ids)->update([ 'history' => \DB::raw('JSON_ARRAY_APPEND(history, "$", JSON_OBJECT("user_id", "144", "action", "cancel", "at", "2021-08-30"))') ]);
- PostgreSQL 环境写法
Model::whereIn('id', $ids)->update([ 'history' => \DB::raw('history || \'[{"user_id":"144","action":"cancel","at":"2021-08-30"}]\'::jsonb') ]);
方法2:封装自定义方法实现你需要的调用形式
你可以在对应Model中添加本地作用域,封装成你想要的appendJson用法:
// 在你的Model类中添加如下方法 public function scopeAppendJson($query, $field, $appendData) { // 以下为MySQL环境的封装示例,PostgreSQL可自行替换对应RAW语句 $jsonStr = json_encode($appendData, JSON_UNESCAPED_UNICODE); return $query->update([ $field => \DB::raw("JSON_ARRAY_APPEND(IFNULL(`{$field}`, '[]'), '$', CAST('{$jsonStr}' AS JSON))") ]); }
封装完成后就可以直接用你预期的写法调用:
Model::whereIn('id', $ids)->appendJson('history', [ 'user_id' => '144', 'action' => 'cancel', 'at' => '2021-08-30' ]);
注意事项
- 需保证目标JSON字段的初始值为数组格式,上面封装的方法已经用
IFNULL做了null值兼容处理 - 封装时对字段名添加了反引号包裹,避免和SQL关键字冲突,使用时不要传入非法字段名即可规避SQL注入风险
内容的提问来源于stack exchange,提问作者TakiDDine
相关产品推荐
相关产品推荐

