<?php declare(strict_types=1); namespace Meibuyu\Micro\Model; use Hyperf\DbConnection\Model\Model ; abstract class BaseModel extends Model { /** * Function addDataToMysql * 批量插入数据到数据库,无则插入,重复则更新 */ public function batchUpdateOrCreateByUniqueKey($data) { $buildInsertBatchSqlStr = $this->buildInsertBatchSqlStr($data); $sql = $buildInsertBatchSqlStr['sql']; return $this->getConnection()->update($sql); } /** * Function buildInsertBatchSqlStr * 组装mysql */ private function buildInsertBatchSqlStr($data) { //从data中 获取更新的字段 if (empty($data)) { return false; } $new_data=[]; $maxdim=$this->getmaxdim($data); if($maxdim==1){ // 兼容一维数组 $new_data[]=$data; }elseif($maxdim>2){ // 大于2维返回false return false; }else{ $new_data=$data; } $keys_arr = []; $datas_arr = []; $where_arr = []; foreach ($new_data as $k => $v) { if (!$keys_arr) { $keys_arr = array_keys($v); } foreach ($v as $k2=>&$v2){ if(is_string($v2)){ $v2="'".addslashes($v2)."'"; } } //数据重组 $onedata = "( " . implode(',', $v) . " )"; $datas_arr[] = $onedata; unset($onedata); } // 组装格式 pt_uid=VALUES(pt_uid), foreach ($keys_arr as $k2 => $v2) { $where_arr[] = "$v2 = VALUES($v2)"; } $keys_str = implode(',', $keys_arr); $datas_str = implode(',', $datas_arr); $where_str = implode(',', $where_arr); $sql = ""; if ($keys_str && $datas_str && $where_str) { $table = $this->getTable(); $sql = " INSERT INTO $table ( $keys_str ) VALUES $datas_str ON DUPLICATE KEY UPDATE $where_str"; } unset($keys_str, $where_str); return ['sql' => $sql, 'count' => count($datas_arr)]; } /** * Function getmaxdim * 数组维数 */ private function getmaxdim($vDim){ if(!is_array($vDim)) return 0; else { $max1 = 0; foreach($vDim as $item1) { $t1 = $this->getmaxdim($item1); if( $t1 > $max1) $max1 = $t1; } return $max1 + 1; } } /** * 批量更新数组 有则 * @param $data array 待更新的数据,二维数组格式 * @param string $field string 值不同的条件,默认为id * @return bool|string */ public function batchUpdateByField($data, $field = null) { if(is_null($field)) $field = $this->getKeyName(); if (!is_array($data) || !$field ) { return false; } $updates = $this->parseUpdate($data, $field); // 获取所有键名为$field列的值,值两边加上单引号,保存在$fields数组中 // array_column()函数需要PHP5.5.0+,如果小于这个版本,可以自己实现, // 参考地址:http://php.net/manual/zh/function.array-column.php#118831 $fields = array_column($data, $field); $fields = implode(',', array_map(function($value) { return "'".$value."'"; }, $fields)); $sql = sprintf( "UPDATE `%s` SET %s WHERE `%s` IN (%s) ", $this->getTable(), $updates, $field, $fields ); return $this->getConnection()->update($sql); } /** * 将二维数组转换成CASE WHEN THEN的批量更新条件 * @param $data array 二维数组 * @param $field string 列名 * @return string sql语句 */ private function parseUpdate($data, $field) { $sql = ''; $keys = array_keys(current($data)); foreach ($keys as $column) { if($column==$keys) continue; $sql .= sprintf("`%s` = CASE `%s` \n", $column, $field); foreach ($data as $line) { $sql .= sprintf( "WHEN '%s' THEN '%s' \n", $line[$field], !is_numeric($line[$column])?addslashes($line[$column]):$line[$column], ); } $sql .= "END,"; } return rtrim($sql, ','); } }