準備條件:
1、首先準備兩張表:
customer(用戶表)(id, name)
order(訂單表)(id, customer_id, price)
customer 表和 order 表之間是一對多的關係,通過 customer_id 字段關聯。
2、建立相應的模型文件 customer.php 和 order.php 文件。
<?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(),程序會報錯。