Yii2.0 關聯查詢

最近一直在看網上視頻學習Yii2.0,剛學習了關聯查詢這一章,就把自己的學習筆記總結了一下。關聯查詢在實際中用的是比較多的,其實在關聯查詢中,還有幾個小的知識點需要注意,比如:hasMany和hasOne,joinWith 和 with的區別等,如果有理解不正確的地方,歡迎指正!

1.表的關聯設計

a)Customer表
—-id 用戶ID
—-name 用戶名

b)Order表
—-id 價格ID
—-customer_id 用戶ID
—-price 價格

customer表中的id 和Order表中的 customer_id 是關聯的

2.在models中的寫法

a)在customer表中加上方法getOrders();(這個方法中的get是固定的,而Orders是可以隨便取的,但是我們一般傾向於和表名一致);

public function getOrders(){    
$orders=$this->hasMany(Order::className(),['customer_id'=>'id'])->asArray()->all();
    return $orders;
   }

b)在price表中加上方法getCustomer();

public function getCustomer(){      
$customer=$this->hasOne(Customer::className(),['id'=>'customer_i  d'])->asArray()->one();
    return $customer;
}

注意:在兩個模型類中,你會發現getOrders方法中用的是hasMany,而在getCustomer方法中用的是hasOne,他們有什麼區別呢?

i.通過customer來查詢order,一個顧客可能會有多個訂單,所以就調用的是hasMany(),所以說,hasMany 就是用於一對多的情況;

ii.通過訂單來查詢顧客,一個訂單隻能屬於一個顧客,所以就調用的是hasOne(),所以說,hasOne 就是用於一對一的情況;

3.在Controllers中調用的寫法

a)通過顧客查詢訂單:

public function actionOrder(){
//查新顧客信息
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
//查詢出張三對應的所有訂單
$orders=$customer->getOrders();
var_dump($orders);
}

注意:以上$orders=$customer->getOrders();這行代碼也可以寫爲:$orders=$customer->orders;(這個orders就是models中的getorders中的orders),不過如果這樣寫的話,model中的方法最後的all()或one,方法就不能調用了,因爲我們這樣用時,$orders=$customer->orders;它會根據我們model中的hasMany 和 hasOne在後邊自動補全all 或 one.

b)通過訂單查詢顧客:

public function actionCustomer(){
//查詢出訂單
$order=Order::find()->where(['id'=>1])->one();
//查詢出顧客
$cus=$price->getCustomer();
var_dump($cus);
}

c)其實在控制器中我們也可以直接寫成以下形式:

public function actionOrder(){
$customer=Customer::find()->where(['name'=>'zhangsan'])->one();
$orders=$customer->hasMany(Price::className(),['customer_id'=>'id'])->asArray()->all();
$orders=$customer->getOrders();
}

就是把model中封裝的那個方法直接寫在控制器中,但是這樣寫有個缺陷,就是當我們的表名或關聯字段發生改變的時候,就需要修改控制器,如果我們在多個控制器中都查詢了,修改起來就比較複雜,封裝在models中之後,就直接修改對應的model就ok了。

4.關聯查詢的性能問題

a)關聯查詢的多次查詢

//查詢出所有的customer
$customer=Customer::find()->all();//select * from customer
foreach($customers as $customer){
//把每個顧客對應的訂單都查詢出來
$orders[]=$customer->orders;//=>select * from order where customer_id =....如果是100個customer,就要調用100次查詢
}

以上的寫法,如果是100個顧客,就會查詢數據庫101次,查用戶一次,根據用戶查訂單100次
b)優化

$customers=Customer::find()->with('orders')->all();
//這樣優化之後,相當於:
select * from customer 
select * from orders where customer_id in (....);

之前要查詢101次的,現在只需要查詢2次就可以了
注意:with 中的“orders”,也是model中的getOrders中的orders

發佈了23 篇原創文章 · 獲贊 21 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章