1. 程式人生 > >yii2.0 基於ActiveRecord 封裝的curd操作

yii2.0 基於ActiveRecord 封裝的curd操作

最近在用yii2.0 進行系統重構,需要一個相容之前框架的curd 的一種呼叫方式,所以對activeRecord 類進行了繼承和封裝,實現基本的curd、強制主從切換等方法,同時相容ActiveRecord 的原生方法。

程式碼如下:

<?php

/**
 * Created by PhpStorm.
 * User: wangyaofeng
 * Date: 17-8-11
 * Time: 下午12:06
 */
namespace common\components;
use Yii;
use \yii\db\ActiveRecord;
abstract class ModelBasic extends ActiveRecord
{
    //標誌位 是否強制走主庫
    protected static $_master = false;
    //標誌位 資料庫配置對應的key
    protected static $_configKey = 'Shop';
    //對應的表明
    protected static $_tableName = 'shop';
    //對應的表字首
    protected static $_tablePrefix = 'cc_';
    public  $param = array();
    protected static $_dbArray = array();
    protected $_transaction = null;
    //配置引數
    public function setParam($_configKey,$tableName,$_tablePrefix='cc_'){
        self::$_configKey = $_configKey;
        self::$_tableName = $tableName;
        self::$_tablePrefix = $_tablePrefix;
    }
    //配置表名
    public static function tableName()
    {
        return '{{%'.self::$_tableName.'}}';
    }
    //配置db主從和字首配置
    public static function  getDbConfig($configName='Shop',$master=false){
        $config = Yii::$app->params[$configName];
        //應對庫相同,表字首不同的情況
        $config['masterConfig']['tablePrefix'] = self::$_tablePrefix;
        $config['slaveConfig']['tablePrefix'] = self::$_tablePrefix;
        $key = md5($configName);
        /*if(!isset(self::$_dbArray[$key])){
            self::$_dbArray[$key] = Yii::createObject($config);
        }*/

        //返回主庫例項
        if(!isset(self::$_dbArray[$key])){
            self::$_dbArray[$key] = Yii::createObject($config);
        }
        switch ($master){
            case false:return self::$_dbArray[$key]->getSlave();break;
            case true:return self::$_dbArray[$key]->getMaster();break;
            default:return self::$_dbArray[$key];
        }
        //返回從庫例項


    }
    //重寫 ActiveRecord 靜態方法 根據引數切換主從
    public static function getDb(){
        return self::getDbConfig(self::$_configKey,self::$_master);
    }
    //查詢方法
    public  function selectLogic($field,$where,$order,$limit,$page,$count=false,$master=false){
        try{
            //要求強制切主或者 有事務存在的時候 要切回主庫
            if($master==true || !empty($this->_transaction)){
                self::$_master = true;
            }else{
                self::$_master = false;
            }
            $offset = ($page-1)*$limit;
            $basic = $this->find()->where($where)->orderBy($order)->limit($limit)->offset($offset)->select($field);
            $result['data'] = $basic->asArray()->all();
            //$sql = $basic->createCommand()->getRawSql();
            if($count==true){
                $result['count'] = $this->find()->where($where)->count('*');
            }
            return $result;
        }catch (\Exception $e){
            return $e->getMessage();
        }
    }
    //插入方法 強制切主  如果主鍵id存在返回主鍵id,否則返回 true/false
    public  function insertLogic($data = array()){
        self::$_master = true;
        foreach($data as $key=>$val){
            $this->$key = $val;
        }
        $result = $this->insert();
        $insertId = $this->primaryKey;
        if($result==true && !empty($insertId)){
            return $insertId;
        }
        return $result;
    }
    //批量插入方法 強制切主
    public function insertAllLogic($data = array()){
        self::$_master = true;
        $columns = array();
        $rows = array();
        foreach($data as $key =>$val){
            $rows[$key] = array_values($val);
            if(empty($columns)){
                $columns = array_keys($val);
            }
        }
        $basic = self::getDb()->createCommand();
        $result = $basic->batchInsert(self::$_tablePrefix.self::$_tableName,$columns,$rows)->execute();
        //var_dump($basic->getRawSql());
        return $result;
    }
    //更新方法
    public function updateLogic($data,$where){
        self::$_master = true;
        $result = $this->updateAll($data,$where);
        //var_dump($this->find()->createCommand()->getRawSql());
        return $result;
    }
    //update更新 是否帶校驗
    public function updateLoginc2($data,$where,$runValidation=false){
        self::$_master = true;
        $model = $this->findOne($where);
        foreach($data as $key=>$val){
            $model->$key = $val;
        }
        $result = $model->update($runValidation);
        return $result;
    }
    //刪除方法
    public  function deleteLogic($where){
        self::$_master = true;
        $result = $this->deleteAll($where);
        return $result;
    }
    //開啟一個事物
    public  function begin(){
        //事物應該在主庫才會生效 因為自動走的讀寫分離,寫是主庫
        self::$_master = true;
        $this->_transaction  = self::getDb()->beginTransaction();
    }
    //提交一個事物
    public  function commit(){
        if(!empty($this->_transaction)){
            $this->_transaction->commit();
        }
    }
    //回退一個事物
    public  function rollback(){
        if(!empty($this->_transaction)){
            $this->_transaction->rollBack();
        }

    }

}

呼叫例項:
<?php
/**
 * Created by PhpStorm.
 * User: wangyaofeng
 * Date: 17-8-24
 * Time: 下午5:02
 */

namespace backend\models\shop;

use common\components\ModelBasic;
class AdminRecall extends ModelBasic
{
    /**
     * 初始化 配置 例項
     * @since 2017-08-31
     * @lastModifyTime   2017-08-31
     * @author 
     * @lastModify 
     * @return null
     */
    public function __construct()
    {
        //db配置對應的key
        $this->param['configKey'] = 'Shop';
        //表名
        $this->param['tableName'] = 'admin_recall';
        //字首
        $this->param['tablePrefix'] = 'cc_';
        //設定配置
        $this->setParam($this->param['configKey'],$this->param['tableName'],$this->param['tablePrefix']);
    }
    /**
     * 插入 資料 例項
     * @since 2017-08-31
     * @lastModifyTime   2017-08-31
     * @author 
     * @lastModify 
     * @return null
     */
    public function create()
    {
        //開啟事物
        $this->begin();
        $time = time();
        $array['valid_starttime'] = $time;
        $array['valid_endtime'] = $time+86400;
        $array['require'] = 'test';
        $result = $this->insertLogic($array);
        //回滾測試
        $this->rollback();
        return $result;
    }
    /**
     * 批量插入 資料 例項
     * @since 2017-08-31
     * @lastModifyTime   2017-08-31
     * @author 
     * @lastModify 
     * @return MaxId
     */
    public function createAll()
    {
        $time = time();
        for($i=0;$i<1;$i++){
            $array[$i]['valid_starttime'] = $time;
            $array[$i]['valid_endtime'] = $time+86400;
            $array[$i]['require'] = 'test'.$i;
        }
        //開始事物
        $this->begin();
        $result = $this->insertAllLogic($array);
        //事物提交例項
        $this->commit();
        return $result;
    }
    /**
     * 更新 資料 例項
     * @since 2017-08-31
     * @lastModifyTime   2017-08-31
     * @author 
     * @lastModify 
     * @return int/num
     */
    public function updateTest()
    {
        $data['require'] = 'hi,test';
        $where= array('in','id',array('141','140'));
        $result = $this->updateLogic($data,$where);
        return $result;
    }
    /**
     * 刪除 資料 例項
     * @since 2017-08-31
     * @lastModifyTime   2017-08-31
     * @author 
     * @lastModify 
* @return true/false */ public function deleteTest() { $where['id'] = 141; $result = $this->deleteLogic($where); return $result; } /** * 查詢 資料 例項 * @since 2017-08-31 * @lastModifyTime 2017-08-31 * @author * @lastModify * @return array */ public function selectTest() { $where = [ 'and', ['<', 'valid_starttime', 1503575727], [ 'and', ['>=', 'id', '100'], ['<=', 'id', '105'], ] ]; $reslut = $this->selectLogic('*',$where,' id desc ',10,1,false,false); return $reslut; }} 資料庫多庫主從配置
<?php
/**
 * Created by PhpStorm.
 * User: wangyaofeng
 * Date: 17-8-11
 * Time: 上午11:10
 */
//資料庫配置,支援 主從,多資料庫配置
return [
    /*多資料庫支援*/
    'Shop' => [
        'class' => 'yii\db\Connection',
        'tablePrefix' =>'cc_',
        'masterConfig' => [
            'username' => 'test',
            'password' => 'test1',
            //'dsn' => 'mysql:host=127.0.0.1;dbname=shop;port=5500',
            'charset' =>'utf8',
        ],
        'masters' => [
            ['dsn' => 'mysql:host=127.0.0.1;dbname=shop;port=5500'],
        ],
        // 配置從伺服器
        'slaveConfig' => [
            'username' => 'test',
            'password' => 'test1',
            'charset'  => 'utf8',
            'tablePrefix' =>'cc_',
            'attributes' => [
                PDO::ATTR_TIMEOUT => 10,
            ],
        ],

        // 配置從伺服器組
        'slaves' => [
            ['dsn' => 'mysql:host=127.0.0.1;dbname=shop;port=5500'],
        ],
    ],
    /*5500  test*/
    'ShopAdmin' =>[
        'class' => 'yii\db\Connection',
        'tablePrefix' =>'cc_',
        'masterConfig' => [
            'username' => 'test_admin',
            'password' => '*********',
            'charset' =>'utf8',
        ],
        'masters' => [
            ['dsn' => 'mysql:host='';dbname=shop_admin;port=5500'],
        ],
        // 配置從伺服器
        'slaveConfig' => [
            'username' => 'test_admin',
            'password' => '**********',
            'charset'  => 'utf8',
            'tablePrefix' =>'cc_',
            'attributes' => [
                PDO::ATTR_TIMEOUT => 10,
            ],
        ],

        // 配置從伺服器組
        'slaves' => [
            ['dsn' => 'mysql:host='';dbname=shop_admin;port=5500'],
        ],
    ]

];

yii2.0 自帶ActiveRecord 方法原生支援,只是對其進行了一層封裝,可以作為model 基類使用,使得db操作更加靈活,查詢(selectLogic)時通過引數還可以強制主從切換,這裡是用作重構過程中更好的利用一些程式碼,而做的一層封裝和基礎方法收攏,從封裝的model基類不在顯示支援連結串列查詢,分享出來僅供參考!