yii2 ActiveRecord多表關聯以及多表關聯搜尋的實現,yii2activerecord_PHP教程

來源:互聯網
上載者:User

yii2 ActiveRecord多表關聯以及多表關聯搜尋的實現,yii2activerecord


一個老生常談的問題。最近通過群裡的反饋,覺得很多人還是沒有去理解這個問題。今天把這個問題講明白了,看看yii2 ActiveRecord是怎麼個多表關聯以及如何去最佳化這個關聯。

情境需求:

假設我們有一張使用者表user和一張使用者渠道表auth,兩張資料表通過user.id和auth.uid進行一對一關聯。現需要在user列表展示auth表的來源渠道source,且該渠道可搜尋。

首先我們先通過gii產生user和auth系列相關的model和操作。此處不做詳細說明,有關gii的操作可參考xxx

我看繼續看重要的幾個操作步驟:

1、找到user表對應的AR模型類 common\models\User.php,在該類檔案中進行關聯auth表

/** *  關聯auth表
* @see http://www.manks.top/yii2_many_ar_relation_search.html */public function getAuth(){ // hasOne要求返回兩個參數 第一個參數是關聯表的類名 第二個參數是兩張表的關聯關係 // 這裡uid是auth表關聯id, 關聯user表的uid id是當前模型的主鍵id return $this->hasOne(common\models\Auth::className(), ['uid' => 'id']);}

設定好了之後,並不代表兩張資料表自動進行關聯了!我們訪問user列表頁(該列表頁採用gii產生,目前我們沒操作過),通過debug查看Database Queries不難發現,實際中的query並沒有進行關聯auth表

2、在gridview中添加關聯表的來源渠道欄位source

widget([    // other codes    'columns' => [        // other columns        'auth.source',    ]]); ?>

有同學感覺疑問了,上面不是說了沒進行關聯嗎,這個怎麼可以直接使用auth.source?

先別急,此時我們開啟debug看看實際的query。

我們會發現有很多類似 select * from `auth` where uid = xxx;之類的操作,如果你的分頁預設20條資料時,會有20個類似的query。

我們先搞明白髮生了什嗎?

實際上這屬於php的基礎知識了。讀取和寫入對象的一個不存在的成員變數時, __get() __set() 魔術函數會被自動調用。yii也是利用了這一點對其進行了實現!

該操作跟大部分人在gridview中封裝方法擷取關聯表資料幾乎一致,但是!20條sql的查詢明顯增加了眾多的開銷。如果這裡是left join操作多好!

3、最佳化sql

我們需要最佳化的是:

20條sql變1條sql

只擷取關聯表需要的欄位

有同學要嚷嚷了,這裡是yii內建的操作,怎麼最佳化?我們回到資料來源的擷取上,發現user列表的資料是通過userSearch model的search方法提供的。

也就是說我們的資料查詢實際上就沒有去進行關聯表查詢!既然如此,我們就在UserSearch加上關聯查詢

$query = User::find();$query->joinWith(['auth']);$query->select("user.*, auth.source");

我們再來重新整理下user列表頁,然後通過debug分析發現有兩條sql引起了我們的注意

SELECT `user`.*, `auth`.`source` FROM `user` LEFT JOIN `auth` ON `user`.`id` = `auth`.`uid` LIMIT 20SELECT * FROM `auth` WHERE `user_id` IN (20個uid);

也就是說我麼已經達到了最佳化sql的目的,通過debug分析發現,DB的查詢時間少了很多。

4、關聯表欄位增加查詢

gridview中的搜尋模型也是通過searchModel實現的,該模型通過rules控制著哪個欄位可搜尋,哪個欄位不可搜尋。

我們現在需要增加關聯表的source可搜尋,因此我們在searchModel中定義一個屬性source且添加到rules中

public $source;public function rules(){    return [    // other rules        ['source', 'safe'],    ];}

接著我們把gridview中的auth.source修改一下

// 'auth.source',[    'attribute' => 'source',    'value' => 'auth.source',    'label' => '渠道來源',],

到這裡我們介面上是ok的,要實現程式上的搜尋還差一步,我們在資料來源擷取的地方加上新增的source條件即可

$query->andFilterWhere([    // other params    'auth.source' => $this->source,]);

http://www.bkjia.com/PHPjc/1140067.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1140067.htmlTechArticleyii2 ActiveRecord多表關聯以及多表關聯搜尋的實現,yii2activerecord 一個老生常談的問題。最近通過群裡的反饋,覺得很多人還是沒有去理解這個...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.