YII2中多表關聯的使用

首先先來講明一下表結構php

表結構sql

如今有訂單表、用戶表、商品清單表、商品庫存表,數據庫

訂單表Order Id Order_id User_id  
用戶表User Id User_id User_name  
商品清單表Order_goods Id Order_id Goods_id  
商品表Goods Id Goods_id Goods_name  
商品庫存表Stock Id Stock-id Goods_id Stock_count

上頁下頁數組

 

 

 

在YII中,若是想直接關聯其餘表進行查詢的話,須要先在模型裏定義它們的關聯緩存

Orderyii

class Order extends \yii\db\ActiveRecord.{

    // 關聯函數以get+要關聯的數據表名來命名

    // 這是獲取下訂單的客戶

    public function getUser(){

        // 第一個參數爲要關聯的子表模型類名,

        // 第二個參數指定 經過子表的user_id,關聯主表的usesr_id字段

        // 這裏寫清楚點大概意思就是User.user_id => Order.user_id

         return $this->hasMany(User::className(), ['user_id' => 'user_id']);
    }
}

hasMany、hasOne使用函數

Yii2中的表之間的關聯有2種,它們用來指定兩個模型之間的關聯。this

  • 一對多:hasMany
  • 一對一:hasOne
  •  
  • 返回結果:這兩個方法的返回結果都爲yii\db\ActiveQuery對象(若是你想最後返回的是標準數組形式,記得加上asArray()參數)
  • 第一個參數:所關聯的模型的類名稱。
  • 第二個參數:是一個數組,其中鍵爲所關聯的模型中的屬性,值爲當前模型中的屬性。

關聯的使用

如今咱們來嘗試獲取一個訂單spa

//獲取訂單信息

$order = Order::findOne(1);

//根據訂單信息獲取到用戶信息

$user = $order->user;

固然你能夠選擇使用with方法,這樣看起來簡潔一些,其中with的參數爲關係的名稱,也就在model裏面定義的getUser中的usercode

//返回訂單信息(包括用戶信息)

$order = Order::find(1)->with('user');

//或者

$order = Order::find(1)->getUser();

上面的代碼會生成並執行以下的sql語句

SELECT * FROM order    WHERE id=1;

SELECT * FROM user     WHERE user.user_id=order.user_id;

從上面能夠看出訪問一個關聯的時候有兩種方法

  • 若是以函數的方式調用,會返回一個 ActiveQuery 對象($customer->getOrders()->all())
  • 若是以屬性的方式調用,會直接返回模型的結果($customer->orders)

關聯結果緩存

若是這時order表發生了改變,咱們但願再次查詢的話

$user = $order->user;

再次獲得訂單的時候你會發現沒有變化。緣由是隻會在第一次執行$order->user的時候纔會去數據庫裏面查詢,而後會把結果緩存起來,之後查詢的時候都不會再執行sql。

那麼若是你想再次執行sql如何作呢?能夠執行

//先釋放緩存

unset($order->user);

$order->user;

跨表查詢

下面重點來了!經過上面表結構的圖能夠看到,User表和Order_goods表示沒有直接關聯的,那麼若是咱們想根據用戶信息查找這個用戶買了哪些商品的話,就勢必須要經過Order表去關聯兩張表。那麼該怎麼作呢?首先仍是model層。由於咱們是根據用戶去查,因此到User的model層去定義關聯。

User

public function getOrder() {
    return $this->hasMany(Order::className(), ['user_id' => 'user_id']);
}

public function getOrderGoods() {
    return $this->hasMany(OrderGoods::className(), ['order_id' => 'order_id'])->
        via('order');
}

這裏注意:getOrderGoods中的第二個order_id是指getOrder關聯的Order中的order_id,第一個order_id是指OrderGoods中的order_id。

可是!咱們還有最簡單的方法,那就是使用SQL語句啦!

$map = 'select
       user.name,
       order.id,
       order_goods.goods_id,
       goods.goods_name,
       stock.stock_count
       from user
       LEFT JOIN order          ON order.user_id = user.user_id
       LEFT JOIN order_goods    ON order_goods.order_id = order.order_id
       LEFT JOIN goods          ON goods.goods_id = order_goods.goods_id
       LEFT JOIN stock          ON stock.goods_id = goods.goods_id';
$list1   = Article::findBySql($map)->asArray()->all();

這樣基本就是整個關聯部分了

相關文章
相關標籤/搜索