BaseModel.php 4.41 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
<?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],
Liu lu's avatar
Liu lu committed
151
                    !is_numeric($line[$column])?addslashes($line[$column]):$line[$column]
152 153 154 155 156 157 158 159 160
                );
            }
            $sql .= "END,";
        }

        return rtrim($sql, ',');
    }

}