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 删除记录实现代码
Mar 12 PHP
PHP simple_html_dom.php+正则 采集文章代码
Dec 24 PHP
浅析PHP页面局部刷新功能的实现小结
Jun 21 PHP
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
Jun 28 PHP
php数组删除元素示例
Mar 21 PHP
Windows下的PHP安装文件线程安全和非线程安全的区别
Apr 23 PHP
Dwz与thinkphp整合下的数据导出到Excel实例
Dec 04 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
Sep 14 PHP
Laravel框架路由和控制器的绑定操作方法
Jun 12 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
Jul 21 PHP
Thinkphp5框架实现图片、音频和视频文件的上传功能详解
Aug 27 PHP
thinkPHP5使用Rabc实现权限管理
Aug 28 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实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
php获得刚插入数据的id 的几种方法总结
2018/05/31 PHP
一段效率很高的for循环语句使用方法
2007/08/13 Javascript
解析John Resig Simple JavaScript Inheritance代码
2012/12/03 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
jQuery实现dialog设置focus焦点的方法
2015/06/10 Javascript
javascript适合移动端的日期时间拾取器
2015/11/10 Javascript
省市二级联动小案例讲解
2016/07/24 Javascript
原生js实现可爱糖果数字时间特效
2016/12/30 Javascript
微信小程序 向左滑动删除功能的实现
2017/03/10 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
基于Bootstrap模态对话框只加载一次 remote 数据的解决方法
2017/07/09 Javascript
Javascript中this关键字指向问题的测试与详解
2017/08/11 Javascript
Angular实现搜索框及价格上下限功能
2018/01/19 Javascript
详解webpack自定义loader初探
2018/08/29 Javascript
JavaScript实现数字前补“0”的五种方法示例
2019/01/03 Javascript
node.js开发辅助工具nodemon安装与配置详解
2020/02/06 Javascript
JS时间戳与日期格式互相转换的简单方法示例
2021/01/30 Javascript
python装饰器使用方法实例
2013/11/21 Python
Python实现的文本编辑器功能示例
2017/06/30 Python
详解Django中间件的5种自定义方法
2018/07/26 Python
Django实现微信小程序的登录验证功能并维护登录态
2019/07/04 Python
Python 使用多属性来进行排序
2019/09/01 Python
浅析Python requests 模块
2020/10/09 Python
Python 中Operator模块的使用
2021/01/30 Python
金融专业个人的自我评价
2013/10/18 职场文书
乡村卫生服务一体化管理实施方案
2014/03/30 职场文书
留学经费担保书
2014/05/12 职场文书
领导班子整改措施
2014/10/24 职场文书
金陵十三钗观后感
2015/06/04 职场文书
亮剑精神观后感
2015/06/05 职场文书
处罚决定书范文
2015/06/24 职场文书
《我们的民族小学》教学反思
2016/02/19 职场文书
Django开发RESTful API实现增删改查(入门级)
2021/05/10 Python
阿里云服务器(windows)手动部署FTP站点详细教程
2022/08/05 Servers