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读取IMAP邮件
Oct 09 PHP
一些php技巧与注意事项分析
Feb 03 PHP
新手学习PHP的一些基础知识分享
Jul 27 PHP
php5.3 注意事项说明
Jul 01 PHP
使用PHP下载CSS文件中的图片的代码
Sep 24 PHP
php使用百度翻译api示例分享
Jan 31 PHP
thinkphp配置连接数据库技巧
Dec 02 PHP
php获取从html表单传递数组的方法
Mar 20 PHP
PHP中array_keys和array_unique函数源码的分析
Feb 26 PHP
php封装的smarty类完整实例
Oct 19 PHP
ThinkPHP实现简单登陆功能
Apr 28 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
Aug 05 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
在Mac OS上自行编译安装Apache服务器和PHP解释器
2015/12/24 PHP
Javascript异步编程的4种方法让你写出更出色的程序
2013/01/17 Javascript
jQuery中获取checkbox选中项等操作及注意事项
2013/11/24 Javascript
JS实现弹性漂浮效果的广告代码
2015/09/02 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
AngularJS+Bootstrap实现多文件上传与管理
2016/11/08 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
2017/01/16 Javascript
jQuery插件HighCharts绘制简单2D柱状图效果示例【附demo源码】
2017/03/21 jQuery
vue实现树形菜单效果
2018/03/19 Javascript
使用layui 渲染table数据表格的实例代码
2018/08/19 Javascript
vue生成文件本地打开查看效果的实例
2018/09/06 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
2019/05/21 Javascript
Vue之beforeEach非登录不能访问的实现(代码亲测)
2019/07/18 Javascript
JS实现页面跳转与刷新的方法汇总
2019/08/30 Javascript
JsonServer安装及启动过程图解
2020/02/28 Javascript
node.js如何操作MySQL数据库
2020/10/29 Javascript
谈谈如何手动释放Python的内存
2016/12/17 Python
详解python实现读取邮件数据并下载附件的实例
2017/08/03 Python
python实现复制文件到指定目录
2019/10/16 Python
Python API自动化框架总结
2019/11/12 Python
wxpython绘制圆角窗体
2019/11/18 Python
python基于celery实现异步任务周期任务定时任务
2019/12/30 Python
tensorflow安装成功import tensorflow 出现问题
2020/04/16 Python
Python3爬虫中识别图形验证码的实例讲解
2020/07/30 Python
selenium切换标签页解决get超时问题的完整代码
2020/08/30 Python
Python监听剪切板实现方法代码实例
2020/11/11 Python
金融专业个人求职信范文
2013/11/28 职场文书
英语专业学生个人求职信范文
2014/01/06 职场文书
《藏戏》教学反思
2014/02/11 职场文书
致垒球运动员加油稿
2014/02/16 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
2014年学校安全工作总结
2014/11/13 职场文书
2015年环卫工作总结
2015/04/28 职场文书
阿甘正传观后感
2015/06/01 职场文书
2015年小学生暑假总结
2015/07/13 职场文书
导游词之平津战役纪念馆
2019/11/04 职场文书