• yii2 ExtendActiveRecordModel.php


    <?php
    // model 基本模型类
    namespace appextend;
    
    use yiidataPagination;
    use yiiwidgetsLinkPager;
    use appcomponentsFunctions;
    
    class ExtendActiveRecordModel extends yiidbActiveRecord {
        /**
         * 重载 读取数据库配置
         */
        public function buildInCondition($operator, $operands, &$params) {
            if (! isset ( $operands [0], $operands [1] )) {
                throw new Exception ( "Operator '$operator' requires two operands." );
            }
            
            list ( $column, $values ) = $operands;
            
            if ($column === [ ]) {
                // no columns to test against
                return $operator === 'IN' ? '0=1' : '';
            }
            
            if ($column instanceof Traversable || count ( $column ) > 1) {
                return $this->buildCompositeInCondition ( $operator, $column, $values, $params );
            } elseif (is_array ( $column )) {
                $column = reset ( $column );
            }
            
            $sqlValues = [ ];
            foreach ( $values as $i => $value ) {
                if (is_array ( $value ) || $value instanceof ArrayAccess) {
                    $value = isset ( $value [$column] ) ? $value [$column] : null;
                }
                if ($value === null) {
                    $sqlValues [$i] = 'NULL';
                } else {
                    $phName = self::PARAM_PREFIX . $i; // count($params) 改为 $i $$Richard IN 条件慢
                    $params [$phName] = $value;
                    $sqlValues [$i] = $phName;
                }
            }
            
            if (empty ( $sqlValues )) {
                return $operator === 'IN' ? '0=1' : '';
            }
            
            if (strpos ( $column, '(' ) === false) {
                $column = $this->db->quoteColumnName ( $column );
            }
            
            if (count ( $sqlValues ) > 1) {
                return "$column $operator (" . implode ( ', ', $sqlValues ) . ')';
            } else {
                $operator = $operator === 'IN' ? '=' : '<>';
                return $column . $operator . reset ( $sqlValues );
            }
        }
        
        /**
         * 重载 读取数据库配置
         */
        static public function getDb() {
            if (Yii::$app->params ['dbSelect'] == 'main') {
                return Yii::$app->maindb;
            } elseif (Yii::$app->params ['dbSelect'] == 'company') {
                // 获取 companydsn
                if (Yii::$app->params ['dsnSelect']) {
                                $companyDSN = require (__DIR__ . '/../config/companydsn.php');
                                Yii::$app->companydb->dsn = $companyDSN [Yii::$app->params ['dsnSelect']];
                            }
                return Yii::$app->companydb;
            } elseif (Yii::$app->params ['dbSelect'] == 'companyold') {
                return Yii::$app->companyolddb;
            } elseif (Yii::$app->params ['dbSelect'] == 'thirdparty') {
                return Yii::$app->thirdpartydb;
            } elseif (Yii::$app->params ['dbSelect'] == 'phathirdparty') {
                return Yii::$app->phathirdpartydb;
            } elseif(Yii::$app->params ['dbSelect'] == 'yht'){
                return Yii::$app->yhtdb;
            }
        }
        
        /**
         * 获取列表数据
         */
        static public function baseFindList($class, $condition = []) {
            // 初始化ActiveQuery::find();
            $activeQuery = $class->find ();
            
            // 查询字段
            if (isset ( $condition ['SELECT'] ) && $condition ['SELECT']) {
                $activeQuery->select ( $condition ['SELECT'] );
            }
            // 关联表
            if (isset ( $condition ['WITH'] ) && $condition ['WITH']) {
                // 判断是否立即加载 默认否
                if (isset ( $condition ['WITHEAGER'] ) && $condition ['WITHEAGER']) {
                    $activeQuery->joinWith ( $condition ['WITH'], $condition ['WITHEAGER'] );
                } else {
                    $activeQuery->joinWith ( $condition ['WITH'], false );
                }
            }
            // 排序条件
            if (isset ( $condition ['ORDER'] ) && $condition ['ORDER']) {
                $activeQuery->orderBy ( $condition ['ORDER'] );
            }
            // 分组条件
            if (isset ( $condition ['GROUP'] ) && $condition ['GROUP']) {
                $activeQuery->groupBy ( $condition ['GROUP'] );
            }
            // 分组条件
            if (isset ( $condition ['HAVING'] ) && $condition ['HAVING']) {
                $activeQuery->having ( $condition ['HAVING'] );
            }
            // 截取
            if (isset ( $condition ['LIMIT'] ) && $condition ['LIMIT']) {
                $activeQuery->limit ( $condition ['LIMIT'] );
            }
            // 截取
            if (isset ( $condition ['OFFSET'] ) && $condition ['OFFSET']) {
                $activeQuery->offset ( $condition ['OFFSET'] );
            }
            if (isset ( $condition ['INDEX'] ) && $condition ['INDEX']) {
                $activeQuery->indexBy ( $condition ['INDEX'] );
            }
    
            // 查询条件
            $activeQuery = self::_batchCondition ( $activeQuery, $class->tableName (), $condition );
            // 调试用
            if (isset ( $condition ['DEBUG'] ) && $condition ['DEBUG']) {
                $sql = $activeQuery->createCommand ()->getRawSql ();
                die ( $sql );
            }
                    
            $list = $activeQuery->asArray ()->all ();
            return $list;
        }
        
        /**
         * 获取单条数据
         */
        static public function baseFindRow($class, $condition) {
            // 初始化ActiveQuery::find();
            $activeQuery = $class->find ();
            
            // 查询字段
            if (isset ( $condition ['SELECT'] ) && $condition ['SELECT']) {
                $activeQuery->select ( $condition ['SELECT'] );
            }
            // 关联表
            if (isset ( $condition ['WITH'] ) && $condition ['WITH']) {
                // 判断是否立即加载 默认否
                if (isset ( $condition ['WITHEAGER'] ) && $condition ['WITHEAGER']) {
                    $activeQuery->joinWith ( $condition ['WITH'], $condition ['WITHEAGER'] );
                } else {
                    $activeQuery->joinWith ( $condition ['WITH'], false );
                }
            }
            // 分组条件
            if (isset ( $condition ['GROUP'] ) && $condition ['GROUP']) {
                $activeQuery->groupBy ( $condition ['GROUP'] );
            }
            // 分组条件
            if (isset ( $condition ['HAVING'] ) && $condition ['HAVING']) {
                $activeQuery->having ( $condition ['HAVING'] );
            }
            // 排序条件
            if (isset ( $condition ['ORDER'] ) && $condition ['ORDER']) {
                $activeQuery->orderBy ( $condition ['ORDER'] );
            }
            
            $activeQuery->limit ( 1 ); // findRow 只需要返回单条数据
                                       
            // 查询条件
            $activeQuery = self::_batchCondition ( $activeQuery, $class->tableName (), $condition );
            
            // 调试用
            if (isset ( $condition ['DEBUG'] ) && $condition ['DEBUG']) {
                $sql = $activeQuery->createCommand ()->getRawSql ();
                die ( $sql );
            }
            $row = $activeQuery->asArray ()->one ();
            return $row;
        }
        
        /**
         * 获取翻页数据
         */
        static public function baseFindPage($class, $condition = []) {
            // 初始化ActiveQuery::find();
            $activeQuery = $class->find ();
            
            // 关联表
            if (isset ( $condition ['WITH'] ) && $condition ['WITH']) {
                // 判断是否立即加载 默认否
                if (isset ( $condition ['WITHEAGER'] ) && $condition ['WITHEAGER']) {
                    $activeQuery->joinWith ( $condition ['WITH'], $condition ['WITHEAGER'] );
                } else {
                    $activeQuery->joinWith ( $condition ['WITH'], false );
                }
            }
            // 分组条件
            if (isset ( $condition ['GROUP'] ) && $condition ['GROUP']) {
                $activeQuery->groupBy ( $condition ['GROUP'] );
            }
            // 分组条件
            if (isset ( $condition ['HAVING'] ) && $condition ['HAVING']) {
                $activeQuery->having ( $condition ['HAVING'] );
            }
            
            // 查询条件
            $activeQuery = self::_batchCondition ( $activeQuery, $class->tableName (), $condition );
            // 翻页数据
            $pageParams = isset ( $condition ['PAGEPARAMS'] ) ? $condition ['PAGEPARAMS'] : [ ];
            $dataCount = isset ( $condition ['DATACOUNT'] ) ? $condition ['DATACOUNT'] : '';
            
            $primaryKeyArray = $class->primaryKey ();
            $primaryKey = reset ( $primaryKeyArray );
            if(isset ( $condition ['COUNTSELECT'] )){
                $activeQuery->select ( $condition ['COUNTSELECT'] );
            } else {
                $activeQuery->select ( $class->tableName () . '.' . $primaryKey );
            }
            $dataCount = $activeQuery->count ();
            if (isset ( $condition ['DEBUG'] ) && $condition ['DEBUG']) {
                $sql = $activeQuery->createCommand ()->getRawSql ();
                echo ( $sql.'<br><br>' );
            }
            $pagination = self::_loadPagination ( $activeQuery, $condition ['PAGE'], $condition ['PAGESIZE'], $pageParams, $dataCount );
            
            // Page 方法 在 _loadPagination 方法前 先count一下 再重新赋值select
            if (isset ( $condition ['SELECT'] ) && $condition ['SELECT']) {
                $activeQuery->select ( $condition ['SELECT'] );
            }
            // 排序条件
            if (isset ( $condition ['ORDER'] ) && $condition ['ORDER']) {
                $activeQuery->orderBy ( $condition ['ORDER'] );
            }
            $activeQuery->offset ( $pagination->offset )->limit ( $pagination->limit );
            
            // 调试用
            if (isset ( $condition ['DEBUG'] ) && $condition ['DEBUG']) {
                $sql = $activeQuery->createCommand ()->getRawSql ();
                die ( $sql );
            }
            $list = $activeQuery->asArray ()->all ();
    
            $return ['dataCount'] = $pagination->totalCount;
            $return ['pageCount'] = $pagination->pageCount;
            $return ['currentPage'] = $condition ['PAGE'];
            
            // 判断是否需要显示linkPager PC 需要
            if (isset ( $condition ['PAGELINK'] )) {
                $return ['linkPager'] = LinkPager::widget ( [ 
                        'pagination' => $pagination,
                        'nextPageLabel' => Yii::$app->params ['nextPageLabel'],
                        'prevPageLabel' => Yii::$app->params ['prevPageLabel'] 
                ] );
            }
            
            $return ['list'] = $list;
            
            return $return;
        }
        
        /**
         * 统计数据
         */
        static public function baseFindCount($class, $condition) {
            // 初始化ActiveQuery::find();
            $activeQuery = $class->find ();
    
            // 关联表
            if (isset ( $condition ['WITH'] ) && $condition ['WITH']) {
                $activeQuery->joinWith ( $condition ['WITH'], false );
            }
            
            // 查询条件
            $activeQuery = self::_batchCondition ( $activeQuery, $class->tableName (), $condition );
    
            $condition ['COUNTSELECT'] = 'COUNT(1) AS count';
            // 调试用
            if (isset ( $condition ['DEBUG'] ) && $condition ['DEBUG']) {
                $sql = $activeQuery->createCommand ()->getRawSql ();
                die ( $sql );
            }
    
            $activeQuery->select ( $condition ['COUNTSELECT'] );
    
    //        $count = $activeQuery->count ();
    
            $row = $activeQuery->asArray ()->one ();
    //        Functions::dumpData($row);
            return $row['count'];
        }
        
        /**
         * 保存单条数据 需要验证
         */
        static public function baseSaveRow($class, $primaryKey, $attributes, $scenario = '') {
            if ($primaryKey && isset ( $attributes [$primaryKey] ) && $attributes [$primaryKey]) {
                // 修改
                $model = $class->findOne ( $attributes [$primaryKey] );
                $model->isNewRecord = false;
            } else {
                // 新建
                $model = $class;
                $model->isNewRecord = true;
            }
            
            if ($scenario) {
                $model->scenario = $scenario;
            }
            
            $model->setAttributes ( $attributes ); // 批量赋值属性
            if ($model->validate ()) {
                $model->save ();
                
                if ($primaryKey) {
                    $primaryKeyValue = $model->primaryKey; // 主键ID
                    $return [$primaryKey] = $primaryKeyValue;
                }
                
                $return ['status'] = 0;
            } else {
                $return ['status'] = 1;
                $return ['msg'] = Functions::getModelError ( $model->errors );
            }
            
            return $return;
        }
        
        /**
         * 更新单条数据 不用验证
         */
        static public function baseUpdateRow($class, $condition, $attributes) {
            $model = $class->findOne ( $condition );
            if ($model) {
                foreach ( $attributes as $key => $val ) {
                    $model->$key = $val;
                }
                
                return $model->update ( false );
            } else {
                return false;
            }
        }
        
        /**
         * 单条数据设为无效 默认 is_valid 设置为 0
         */
        static public function baseInvalidRow($class, $condition) {
            $model = $class->findOne ( $condition );
            $model->is_valid = 0;
            
            return $model->update ( false );
        }
        
        /**
         * 单条数据物理删除
         */
        static public function baseDeleteRow($class, $condition) {
            $model = $class->findOne ( $condition );
            if ($model == null) {
                return;
            }
            return $model->delete ();
        }
        
        /**
         * 批量查询条件解析赋值
         *
         * @param $activeQuery 查询对象            
         * @param $tableName 查询表名            
         * @param $condition 条件数组            
         * @return $activeQuery object
         */
        static private function _batchCondition($activeQuery, $tableName, $condition) {
            $SQLoperator = ''; // SQL 操作符
            $SQLfield = ''; // SQL 字段
            
            foreach ( $condition as $key => $val ) {
                // 判断是否存在#
                if (strpos ( $key, '#' ) && $val !== null && $val !== '' && $val !== false && $val !== [ ]) {
                    $arrKey = explode ( '#', $key ); // 解析条件
                    switch ($arrKey [0]) {
                        case 'EQ' :
                            $SQLoperator = '=';
                            break;
                        case 'NEQ' :
                            $SQLoperator = '!=';
                            break;
                        case 'GT' :
                            $SQLoperator = '>';
                            break;
                        case 'LT' :
                            $SQLoperator = '<';
                            break;
                        case 'GTE' :
                            $SQLoperator = '>=';
                            break;
                        case 'LTE' :
                            $SQLoperator = '<=';
                            break;
                        case 'LIKE' :
                            $SQLoperator = 'LIKE';
                            break;
                        case 'NLIKE' :
                            $SQLoperator = 'NOT LIKE';
                            break;
                        case 'REGEXP' :
                            $SQLoperator = 'REGEXP';
                            break;
                        case 'IN' :
                            $SQLoperator = 'IN';
                            break;
                        case 'NIN' :
                            $SQLoperator = 'NOT IN';
                            break;
                    }
                    
                    // 判断是否存在 点 号
                    if (strpos ( $arrKey [1], '.' )) {
                        list ( $joinTableName, $joinTableField ) = explode ( '.', $arrKey [1] );
                        $SQLfield = "`{$joinTableName}`.`{$joinTableField}`";
                    } else {
                        $SQLfield = "`{$tableName}`.`{$arrKey[1]}`";
                    }
                    
                    if (in_array ( $SQLoperator, [ 
                            'IN',
                            'NOT IN' 
                    ] )) {
                        // andWhere $val 数组太大 生成SQL很慢
                        if (is_array ( $val )) {
                            $SQLstring = "'" . implode ( "','", $val ) . "'";
                            $activeQuery->andWhere ( "{$SQLfield} {$SQLoperator} ({$SQLstring})" );
                        } else {
                            $activeQuery->andWhere ( "{$SQLfield} {$SQLoperator} ('{$val}')" );
                        }
                    } else {
                        $activeQuery->andWhere ( [ 
                                // 使用链接符
                                $SQLoperator,
                                // 查询字段
                                $SQLfield,
                                // 查询值
                                $val 
                        ] );
                    }
                } elseif ($key == 'CUSTOM') { // 关键字为CUSTOM 自定义查询条件
                    if (is_array ( $val ) ) {
                        if (is_array ( $val ['param'] ) ) {
                            $isNull = 1;
                            foreach ( $val ['param'] as $pkey => $pval ) {
                                if($pval){
                                    $isNull = 0;
                                    $val ['condition'] = str_replace ( "{param-{$pkey}}", $pval, $val ['condition'] );
                                }
                            }
                            if(!$isNull)
                                $activeQuery->andWhere ( $val ['condition'] );
                        } else {
                            if(!is_array ( $val ['param']) && $val ['param']){
                                $val ['condition'] = str_replace ( '{param}', $val ['param'], $val ['condition'] );
                                $activeQuery->andWhere ( $val ['condition'] );
                            }
                        }
    
                    } else {
                        $activeQuery->andWhere ( $val );
                    }
                } elseif (strpos ( $key, '@' ) && $val !== null && $val !== '' && $val !== false && $val !== [ ]) {
                    $keyArray = explode ( '@', $key ); // 解析条件
                    switch ($keyArray [0]) {
                        case 'IS' : // 判断字段 0: = '' 或者 1: != ''
                            if ($val == '0') {
                                $SQLoperator = '=';
                            } elseif ($val == '1') {
                                $SQLoperator = '!=';
                            }
                            
                            $SQLval = '';
                            break;
                        
                        case 'NULL' : // 判断字段 0: IS NULL 或者 1: IS NOT NULL
                            if ($val == '0') {
                                $SQLoperator = 'IS';
                            } elseif ($val == '1') {
                                $SQLoperator = 'IS NOT';
                            }
                            
                            $SQLval = NULL;
                            break;
                    }
                    
                    // 判断是否存在 .
                    if (strpos ( $keyArray [1], '.' )) {
                        $SQLfield = $keyArray [1];
                    } else {
                        $SQLfield = "{$tableName}.{$keyArray[1]}";
                    }
                    
                    $activeQuery->andWhere ( [ 
                            // 使用链接符
                            $SQLoperator,
                            // 查询字段
                            $SQLfield,
                            // 查询值
                            $SQLval 
                    ] );
                }
            }
            
            // appcomponentsFunctions::dumpData ( $activeQuery );
            
            return $activeQuery;
        }
        
        /**
         * 读取翻页数据
         *
         * @param $activeQuery 查询对象            
         * @param $currentPage 当前页数            
         * @param $pageSize 每页条数            
         * @param $urlParams get参数            
         * @param $dataCount 总记录数
         *            外部传进来的话 不用计算 $activeQuery->count ()
         * @return $pages object
         */
        static private function _loadPagination($activeQuery, $currentPage, $pageSize, $urlParams, $dataCount) {
            $pagination = new Pagination ( [ 
                    'page' => intval ( $currentPage ) - 1,
                    'pageSize' => $pageSize,
                    'totalCount' => $dataCount,
                    'params' => $urlParams 
            ] );
            
            return $pagination;
        }
        
        /**
         * merge 条件
         */
        public function mergeCondition($condition) {
            return $condition;
        }
        
        /**
         * 列表数据
         */
        public function findList($condition = []) {
            $condition = $this->mergeCondition ( $condition );
            return self::baseFindList ( $this, $condition );
        }
        
        /**
         * 单条数据
         */
        public function findRow($condition) {
            $condition = $this->mergeCondition ( $condition );
            return self::baseFindRow ( $this, $condition );
        }
        
        /**
         * 翻页数据
         */
        public function findPage($condition) {
            $condition = $this->mergeCondition ( $condition );
            return self::baseFindPage ( $this, $condition );
        }
        
        /**
         * 统计数据
         */
        public function findCount($condition = []) {
            $condition = $this->mergeCondition ( $condition );
            return self::baseFindCount ( $this, $condition );
        }
        
        /**
         * 保存数据 需要验证
         */
        public function saveRow($attributes, $scenario = '') {
            return self::baseSaveRow ( $this, current ( self::primaryKey () ), $attributes, $scenario );
        }
        
        /**
         * 更新不用验证的属性
         */
        public function updateRow($condition, $attributes) {
            return self::baseUpdateRow ( $this, $condition, $attributes );
        }
        
        /**
         * 单条数据设为无效 逻辑删除
         */
        public function invalidRow($condition) {
            return self::baseInvalidRow ( $this, $condition );
        }
        
        /**
         * 删除单条数据 物理删除
         */
        public function deleteRow($condition) {
            return self::baseDeleteRow ( $this, $condition );
        }
        
        /**
         * 批量insert数据
         */
        public function insertBatch($collectionList, $debug = false) {
            $insertIdArray = [ ]; // 批量插入的ID的数组
            $ceilSize = 5000;
            
            $dbSelect=Yii::$app->params ['dbSelect'];
            
            if ($collectionList) {
                $attributesList = array_keys ( reset ( $collectionList ) );
                $count = count ( $collectionList );
                $ceilCount = ceil ( $count / $ceilSize );
                
                for($i = 0; $i < $ceilCount; $i ++) {
                    $offset = $i * $ceilSize;
                    $length = $ceilSize;
                    $currentList = array_slice ( $collectionList, $offset, $length );
                    
                    Yii::getLogger ()->flushInterval = 5; // https://github.com/yiisoft/yii2/issues/6472 batchInsert 内存泄漏
                                                           
                    // INSERT 一次插入多行 返回插入数量
                    if ($debug) {
                        if($dbSelect=='yht'){
                            $sql = Yii::$app->yhtdb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->getRawSql ();
                        }elseif($dbSelect=='main'){
                            $sql = Yii::$app->maindb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->getRawSql ();
                        }else{
                            $sql = Yii::$app->companydb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->getRawSql ();
                        }
                        die ( $sql );
                    }
                    if($dbSelect=='yht'){
                        $rowCount = Yii::$app->yhtdb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->execute ();
                    }elseif($dbSelect=='main'){
                        $rowCount = Yii::$app->maindb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->execute ();
                    }else{
                        $rowCount = Yii::$app->companydb->createCommand ()->batchInsert ( $this->tableName (), $attributesList, $currentList )->execute ();
                    }
                    
                    if($dbSelect=='yht'){
                        $lastInsertId = Yii::$app->yhtdb->getLastInsertID (); // 返回批量插入 第一条数据插入后返回的的主键ID 比如:插入4,5,6,7 返回4
                    }elseif($dbSelect=='main'){
                        $lastInsertId = Yii::$app->maindb->getLastInsertID (); // 返回批量插入 第一条数据插入后返回的的主键ID 比如:插入4,5,6,7 返回4
                    }else{
                        $lastInsertId = Yii::$app->companydb->getLastInsertID (); // 返回批量插入 第一条数据插入后返回的的主键ID 比如:插入4,5,6,7 返回4
                    }
                    
                    for($j = $lastInsertId; $j < ($lastInsertId + $rowCount); $j ++) {
                        $insertIdArray [] = $j;
                    }
                    
                    // echo "lastInsertId = {$lastInsertId} 
    ";
                    // echo "rowCount = {$rowCount} 
    ";
                }
            }
            
            // var_dump ( $insertIdArray );
            
            return $insertIdArray;
        }
    } 

    srcextendExtendActiveRecordModel.php

  • 相关阅读:
    thinkphp 前台输出
    php的四种定界符
    面试总结
    Git分布式版本控制工具
    Apache Dubbo
    Mybatis03
    Mybatis02
    Mybaitis01
    linux下如何安装webbench
    SpringUtil
  • 原文地址:https://www.cnblogs.com/polax/p/10833618.html
Copyright © 2020-2023  润新知