Yii2中多表關聯查詢

準備條件:

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(),程序會報錯。

 

https://www.cnblogs.com/woods1815/p/11521643.html

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