Maison > cadre php > Laravel > Comment mettre à jour par lots plusieurs enregistrements dans Laravel (empêcher l'injection SQL)

Comment mettre à jour par lots plusieurs enregistrements dans Laravel (empêcher l'injection SQL)

藏色散人
Libérer: 2021-08-25 09:02:17
avant
3357 Les gens l'ont consulté

La colonne tutorielle suivante de Laravel vous présentera comment mettre à jour par lots plusieurs enregistrements dans Laravel, ce qui peut empêcher l'injection SQL. J'espère que cela sera utile aux amis dans le besoin !

Écrit devant

Les enfants qui connaissent Laravel savent que Laravel peut insérer plusieurs enregistrements par lots à la fois, mais il ne met pas à jour plusieurs enregistrements de manière conditionnelle à une fois.

Êtes-vous envieux de saveAll de thinkphp ou de update_batch de ci, mais pourquoi un laravel aussi élégant n'a-t-il pas une méthode de mise à jour par lots similaire ?

Experts

L'a recherché sur Google et a découvert que quelqu'un l'avait déjà écrit sur stackoverflow (https://stackoverflow.com/questions/26133977/laravel-bulk-update), mais cela n'empêche pas l'injection SQL.

Cet article a été ajusté en conjonction avec Eloquent de Laravel pour empêcher efficacement l'injection SQL.

<?php
namespace App\Models;

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

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

    //批量更新
    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;
        }
    }
}
Copier après la connexion

Vous pouvez l'ajuster en fonction de vos propres besoins. Voici un exemple d'utilisation :

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

// 批量更新
app(Students::class)->updateBatch($students);
Copier après la connexion

L'instruction SQL générée est la suivante :

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)
Copier après la connexion

L'efficacité est-elle beaucoup améliorée~

Recommandations associées : Les dernières cinq tutoriels vidéo Laravel

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal