Yii2中findAll()的正確使用姿式/返回爲空的處理辦法

從一次錯誤的操做開始

$buildingObject = Building::findAll("status=1");
  • 1

這個調用看着沒有任何毛病,可是在使用時返回的結果倒是一個空數組。再回過頭來看看數據表中: 
數據表
按照套路來說,查詢後應該返回的是一個對象數組呀!爲何是空呢?百思不得其解,仍是去翻看一下代碼吧。數組

抽絲剝繭從findAll開始

靜態方法findAll()實際上是在yii\db\BaseActiveRecord中的:yii2

/**
 * @inheritdoc
 * @return static[] an array of ActiveRecord instances, or an empty array if nothing matches.
 */
public static function findAll($condition)
{
   return static::findByCondition($condition)->all();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

關於他的實現實際上是調用了本方法中的findByCondition來實現的,從這兒你們也能夠看到高大上的findAll($condition)的實現也是很是簡單的調用了相應的方法來實現的而已。因此其實若是是查詢多條數據的話也可使用其餘方式都很是方便的。yii

抽絲剝繭findByCondition($condition)

靜態方法findAll($condition)實際上是調用了findByCondition這個靜態方法的那麼這個方法是怎麼樣實現的呢?ui

protected static function findByCondition($condition)
{
    $query = static::find();

    if (!ArrayHelper::isAssociative($condition)) {
        // query by primary key
        $primaryKey = static::primaryKey();
        if (isset($primaryKey[0])) {
            $pk = $primaryKey[0];
            if (!empty($query->join) || !empty($query->joinWith)) {
                $pk = static::tableName() . '.' . $pk;
            }
            $condition = [$pk => $condition];
        } else {
            throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
        }
    }

    return $query->andWhere($condition);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

這兒有個誤區你們要注意了,這兒的findByCondition($condition)實際上是ActiveRecord中的而不是BaseActiveRecord,由於繼承關係已經被重寫。 
這部分的代碼也很簡單,重點是在那個if判斷中。spa

if (!ArrayHelper::isAssociative($condition))
  • 1

這個是使用了yii2提供的數組輔助類裏邊的isAssociative來判斷傳入的$condition是否是一個關聯數組。若是不是一個關聯數組則會進入if裏邊進行執行。code

// query by primary key
$primaryKey = static::primaryKey();   //獲取數據表的主鍵
if (isset($primaryKey[0])) {    //判斷主鍵是否爲空
    $pk = $primaryKey[0];
    //判斷有沒有連表查詢,若是有連表查詢就處理成  表名.主鍵   的方式
    if (!empty($query->join) || !empty($query->joinWith)) {
        $pk = static::tableName() . '.' . $pk;
    }
    //直接把條件當作主鍵拼接到條件了!!!
    $condition = [$pk => $condition];
} else {
    //若是主鍵爲空則拋出異常
    throw new InvalidConfigException('"' . get_called_class() . '" must have a primary key.');
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

經常使用用法分析

能夠看出你在findAll($condition)時傳入的參數不是關聯數組的狀況下會當作主鍵處理。可是當作主鍵處理時這兒能夠是數組。好比:對象

$buildingObject = Building::findAll([18,19]);
  • 1

這樣查詢的結果是id爲18和19的兩條數據的對象數組。可是若是你真的要按照id來查詢多條數據的話注意了,參數中的id不能是字符串。例如blog

$buildingObject = Building::findAll("18,19");
  • 1

這樣查詢僅僅能查出id爲18的數據。固然單條數據的查詢仍是推薦使用很是方便的findOne($condition)來查詢。 
固然若是有相等的組合條件也是能夠的,例如:繼承

$buildingObject = Building::findAll(['id'=>[18,19],'status'=>1]);
  • 1

這樣就查詢出id爲18和19並且status字段爲1的數據ci

錯誤示範

固然若是有表達式數組條件和字符串條件都不支持的。例如

//注意如下是錯誤示範
$buildingObject = Building::findAll("id>10");
$buildingObject = Building::findAll([">", "id", 10);
  • 1
  • 2
  • 3

因此在項目中findAll要慎重使用固然使用findAll來查詢的均可以用其餘方法來代替。

 

 

如下屬於原創

findall出來的對象是一個數組,

一種狀況 

$pc=Product_category::findAll(['p'=>'638']);

二種狀況

        // $pc=Product_category::findOne(['p'=>'636']);

        // $pc->delete();

三種狀況

       // $pc=Product_category::findOne('284');

        // $pc->delete();

        二和三等價

一出來的結果要遍歷,若是後面有插入那就慘了。

相關文章
相關標籤/搜索