准備條件:
1、首先准備兩張表:
customer(用戶表)(id, name)
order(訂單表)(id, customer_id, price)
customer 表和 order 表之間是一對多的關系,通過 customer_id 字段關聯。
2、建立相應的模型文件 customer.php 和 order.php 文件。
關聯查詢:
customer.php文件添加getOrder()方法:
<?php namespace app\models; use Yii; /** * This is the model class for table "customer". * * @property int $id * @property string $name 用戶姓名 */ class Customer extends \yii\db\ActiveRecord { /** * 獲取訂單信息 */ public function getOrder() { // 一個用戶對應多個訂單,一對多的關系使用hasMany()關聯 return $this->hasMany(Order::className(), ['customer_id' => 'id'])->asArray(); } }
order.php文件添加getCustomer()方法:
<?php namespace app\models; use Yii; /** * This is the model class for table "order". * * @property int $id * @property int $customer_id 用戶id * @property string $price 價格 */ class Order extends \yii\db\ActiveRecord { /** * 獲取用戶信息 */ public function getCustomer() { // 一個訂單對應一個用戶,一對一的關系使用hasOne()關聯 return $this->hasOne(Customer::className(), ['id' => 'customer_id'])->asArray(); } }
使用:
// 查詢客戶名為張三的訂單信息 $customer = Customer::find()->where(['name' => '張三'])->one(); // 可以通過$customer->getOrder()方法調用customer.php模型中getOrder()方法 $orders = $customer->getOrder()->all(); // 也可以使用$customer->order屬性調用, // 當程序沒有找到order屬性時,PHP會調用__get()函數,程序會自動尋找getOrder()方法調用 // 這里不用加all(),程序會自動識別,如果使用的是hasMany則加all(),hasOne則加上one() $orders = $customer->order; var_dump($orders);exit; // 查詢訂單id為1的客戶信息 $order = Order::find()->where(['id' => 1])->one(); // 調用order.php模型中getCustomer()方法 $customer = $order->customer; var_dump($customer);exit;
with 和 joinWith 的使用:
使用上面的關聯查詢時有個問題就是數據量大的時候性能問題。
$customers = Customer::find()->all(); // 相當於執行 select * from customer foreach ($customers as $customer) { $orders = $customer->order; // 相當於執行 select * from order where customer_id = id; }
假如$customers中有100條數據,則要循環查詢100次,整個程序需要執行SQL語句101次。
這時可以使用with():
// 相當於執行了兩條SQL語句 select * from customer // select * from order where customer_id in(...) $customers = Customer::find()->with('order')->asArray()->all(); foreach ($customers as $customer) { $orders = $customer['order']; // 取得order表的關聯數據 }
joinWith()的用法和with()差不多,joinWith()可以指定連接類型,默認LEFT JOIN連接。
注意點:
1、在模型中定義hasMany,hasOne方法時,最好不要加上all(),one()。調用$customer->order時程序會自動根據使用的是hasMany還是hasOne加上相應的all(), one()。
2、使用with(), joinWith() 查詢時,如果在模型中定義hasMany,hasOne方法時加上了all(),one(),程序會報錯。