【Laravel】Laravel 5.8 批量更新數據庫


背景
Laravel 中一般都是用 ORM 操作數據庫的,但是遇到批量操作很多數據的時候如果還是使用 ORM 對象進行 save() 則會造成數據庫壓力過大,增加沒必要的消耗。

具體實現
該方法是 Laravel 5.8 版本基礎上修改的,其他版本或者其他框架則需要靈活調整。
基本思路是把二維數組進行拆分,組裝成原生 SQL 一次性修改數據庫的數據。

/**
 * 批量更新數據庫
 * @param $tableName
 * @param array $multipleData
 * @param string $where
 * @return bool|int
 */
private function updateBatch($tableName , $multipleData = [], $where = '')
{
    $updateSql = '';
    try {
        if (empty($multipleData)) {
            throw new \Exception("數據不能為空");
        }
        $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);
        $updateSql = rtrim($updateSql, ", ") . $where;
        // 傳入預處理sql語句和對應綁定數據
        return DB::update($updateSql, $bindings);
    } catch (\Exception $e) {
        Log::error('批量保存失敗,sql=' . $updateSql.',結果='. $e->getMessage());
        return false;
    }

}

調用方法
只需要依次傳遞表名、二維數組、where 條件即可

...
//批量更新數據
$data = [];
foreach ($list as $value) {
    $data[] = [
        'user_id' => $value['user_id'],
        'name' => $value['name'],
        'author' => 'HongXunPan'
    ];
}

$chunk_datas = array_chunk($data, 200, true);

foreach ($chunk_datas as $chunk_data) {

    $where = ' WHERE user_id in (' .implode(',', array_column($chunk_data, 'user_id')).')';
    $this->updateBatch($ORM->getTable(), $chunk_data, $where);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM