BatchUpdateService.php 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. namespace App\Services\common;
  3. use App\Services\LogService;
  4. use Illuminate\Support\Facades\DB;
  5. class BatchUpdateService
  6. {
  7. public function batchUpdate($tableName = '', $multipleData = array(), $connection = 'mysql')
  8. {
  9. if (count($multipleData) == 1) {
  10. return false;
  11. }
  12. if ($tableName ?? false && !empty($multipleData)) {
  13. // column of fields to update
  14. $updateColumns = $multipleData[0];
  15. // table primary key
  16. $referenceColumn = $updateColumns[0];
  17. unset($multipleData[0]);
  18. if (count($multipleData) <= 200) {
  19. return $this->batchHandle($tableName, $updateColumns, $referenceColumn, $multipleData, $connection);
  20. } else {
  21. $chunk_datas = array_chunk($multipleData, 200, true);
  22. $bool = true;
  23. foreach ($chunk_datas as $chunk_data) {
  24. $is_successful = $this->batchHandle($tableName, $updateColumns, $referenceColumn, $chunk_data, $connection);
  25. $bool = $is_successful && $bool;
  26. }
  27. return $bool;
  28. }
  29. } else {
  30. return false;
  31. }
  32. }
  33. private function batchHandle($tableName, $updateColumns, $referenceColumn, $multipleData, $connection = 'mysql')
  34. {
  35. $updateSql = "UPDATE " . $tableName . " SET ";
  36. $sets = [];
  37. $bindings = [];
  38. foreach ($updateColumns as $updateColumn) {
  39. $setSql = ' `' . $updateColumn . '` = CASE';
  40. foreach ($multipleData as $multipleDatum) {
  41. $setSql .= ' WHEN ' . $referenceColumn . ' = ? THEN ? ';
  42. $bindings[] = $multipleDatum[$referenceColumn];
  43. $bindings[] = $multipleDatum[$updateColumn];
  44. }
  45. $setSql .= ' ELSE `' . $updateColumn . "` END";
  46. $sets[] = $setSql;
  47. }
  48. $updateSql .= implode(',', $sets);
  49. $whereIn = data_get($multipleData, '*.' . $referenceColumn);
  50. $bindings = array_merge($bindings, $whereIn);
  51. $whereIn = rtrim(str_repeat('?,', count($whereIn)), ',');
  52. $updateSql = rtrim($updateSql, ", ") . " WHERE `" . $referenceColumn . "` IN (" . $whereIn . ")";
  53. try {
  54. // DB::update
  55. $bool = DB::connection($connection)->update($updateSql, $bindings);
  56. LogService::log(__METHOD__, __FUNCTION__, '批量更新' . count($multipleData) . $tableName . $updateSql . json_encode($bindings));
  57. return $bool;
  58. } catch (\Exception $e) {
  59. LogService::log(__METHOD__, __FUNCTION__, '批量更新失败' . count($multipleData) . $tableName . $updateSql . json_encode($bindings) . $e->getMessage() . $e->getTraceAsString());
  60. return false;
  61. }
  62. }
  63. public function batchUpdateItself($tableName, $column, array $params, $connection = 'mysql')
  64. {
  65. $sql = "UPDATE ".$tableName;
  66. $sql .= " SET ".$column." = CASE".$column;
  67. foreach ($params as $key => $value){
  68. $sql .= " WHEN ".$key." THEN ".$value;
  69. }
  70. $sql .= "END WHERE ".$column." IN (".implode(',',array_keys($params)).")";
  71. try {
  72. $bool = DB::connection($connection)->update($sql);
  73. LogService::log(__METHOD__, __FUNCTION__, '批量更新本身' .$sql);
  74. return $bool;
  75. }catch (\Exception $e){
  76. LogService::log(__METHOD__, __FUNCTION__, '批量更新失败 SQL:(' . $sql .") 堆栈:". $e->getMessage() . $e->getTraceAsString());
  77. return false;
  78. }
  79. }
  80. }