laravel实现批量更新多条记录的方法示例


Posted in PHP onOctober 22, 2017

前言

相信熟悉laravel的童鞋都知道,laravel有批量一次性插入多条记录,却没有一次性按条件更新多条记录。

是否羡慕thinkphp的saveAll,是否羡慕ci的update_batch,但如此优雅的laravel怎么就没有类似的批量更新的方法呢?

高手在民间

Google了一下,发现stackoverflow( https://stackoverflow.com/questions/26133977/laravel-bulk-update )上已经有人写好了,但是并不能防止sql注入。

本篇文章,结合laravel的Eloquent做了调整,可有效防止sql注入。

示例代码

<?php
namespace App\Models;

use DB;
use Illuminate\Database\Eloquent\Model;

/**
 * 学生表模型
 */
class Students extends Model
{
 protected $table = 'students';

 //批量更新
 public function updateBatch($multipleData = [])
 {
  try {
   if (empty($multipleData)) {
    throw new \Exception("数据不能为空");
   }
   $tableName = DB::getTablePrefix() . $this->getTable(); // 表名
   $firstRow = current($multipleData);

   $updateColumn = array_keys($firstRow);
   // 默认以id为条件更新,如果没有ID则以第一个字段为条件
   $referenceColumn = isset($firstRow['id']) ? 'id' : current($updateColumn);
   unset($updateColumn[0]);
   // 拼接sql语句
   $updateSql = "UPDATE " . $tableName . " SET ";
   $sets  = [];
   $bindings = [];
   foreach ($updateColumn as $uColumn) {
    $setSql = "`" . $uColumn . "` = CASE ";
    foreach ($multipleData as $data) {
     $setSql .= "WHEN `" . $referenceColumn . "` = ? THEN ? ";
     $bindings[] = $data[$referenceColumn];
     $bindings[] = $data[$uColumn];
    }
    $setSql .= "ELSE `" . $uColumn . "` END ";
    $sets[] = $setSql;
   }
   $updateSql .= implode(', ', $sets);
   $whereIn = collect($multipleData)->pluck($referenceColumn)->values()->all();
   $bindings = array_merge($bindings, $whereIn);
   $whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
   $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";
   // 传入预处理sql语句和对应绑定数据
   return DB::update($updateSql, $bindings);
  } catch (\Exception $e) {
   return false;
  }
 }
}

可以根据自己的需求再做调整,下面是用法实例:

// 要批量更新的数组
$students = [
 ['id' => 1, 'name' => '张三', 'email' => 'zhansan@qq.com'],
 ['id' => 2, 'name' => '李四', 'email' => 'lisi@qq.com'],
];

// 批量更新
app(Students::class)->updateBatch($students);

生成的SQL语句如下:

UPDATE pre_students
SET NAME = CASE
WHEN id = 1 THEN
 '张三'
WHEN id = 2 THEN
 '李四'
ELSE
 NAME
END,
 email = CASE
WHEN id = 1 THEN
 'zhansan@qq.com'
WHEN id = 2 THEN
 'lisi@qq.com'
ELSE
 email
END
WHERE
 id IN (1, 2)

是不是效率又提高了一大截呢~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
php采集速度探究总结(原创)
Apr 18 PHP
PHP得到mssql的存储过程的输出参数功能实现
Nov 23 PHP
php+mysqli批量查询多张表数据的方法
Jan 29 PHP
php递归法读取目录及文件的方法
Jan 30 PHP
yii2.0实现验证用户名与邮箱功能
Dec 22 PHP
必须收藏的php实用代码片段
Feb 02 PHP
PHP重定向与伪静态区别
Feb 19 PHP
PHP获取文件扩展名的方法实例总结
Jun 10 PHP
PHP命名空间namespace及use的简单用法分析
Aug 03 PHP
PHP Include文件实例讲解
Feb 15 PHP
PHP实现的用户注册表单验证功能简单示例
Feb 25 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
May 14 PHP
利用PHP获取汉字首字母并且分组排序详解
Oct 22 #PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
Oct 22 #PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 #PHP
PHP静态延迟绑定和普通静态效率的对比
Oct 20 #PHP
php+ajax实现仿百度查询下拉内容功能示例
Oct 20 #PHP
详解cookie验证的php应用的一种SSO解决办法
Oct 20 #PHP
thinkPHP5项目中实现QQ第三方登录功能
Oct 20 #PHP
You might like
PHP防盗链代码实例
2014/08/27 PHP
去掉gridPanel表头全选框的小例子
2013/07/18 Javascript
jQuery中get()方法用法实例
2014/12/27 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
jQuery使用zTree插件实现树形菜单和异步加载
2016/02/25 Javascript
jquery.validate[.unobtrusive]和Bootstrap实现tooltip错误提示问题分析
2016/10/30 Javascript
浅谈js函数的多种定义方法与区别
2016/11/29 Javascript
原生JS实现几个常用DOM操作API实例
2017/01/19 Javascript
js 原型对象和原型链理解
2017/02/09 Javascript
Vue 中使用vue2-highcharts实现top功能的示例
2018/03/05 Javascript
p5.js实现斐波那契螺旋的示例代码
2018/03/22 Javascript
Vue实现点击时间获取时间段查询功能
2020/08/21 Javascript
微信小程序实现顶部导航特效
2019/01/28 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
2019/04/26 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
node.js使用yargs处理命令行参数操作示例
2020/02/11 Javascript
简单了解常用的JavaScript 库
2020/07/16 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python编写电话薄实现增删改查功能
2016/05/07 Python
在python中pandas的series合并方法
2018/11/12 Python
python3 实现一行输入,空格隔开的示例
2018/11/14 Python
python实现年会抽奖程序
2019/01/22 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
python selenium 查找隐藏元素 自动播放视频功能
2019/07/24 Python
Python做图像处理及视频音频文件分离和合成功能
2020/11/24 Python
Selenium Webdriver元素定位的八种常用方式(小结)
2021/01/13 Python
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
Ajxa常见问题都有哪些
2014/03/26 面试题
大学生毕业自我鉴定
2013/11/06 职场文书
2014年上半年工作自我评价
2014/01/18 职场文书
民事赔偿协议书
2014/11/02 职场文书
2016年优秀团支部事迹材料
2016/02/26 职场文书
使用Selenium实现微博爬虫(预登录、展开全文、翻页)
2021/04/13 Python
MySQL中日期型单行函数代码详解
2021/06/21 MySQL
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android