關(guān)聯(lián)預(yù)載入

關(guān)聯(lián)預(yù)載入

版本 功能調(diào)整
5.0.7 嵌套關(guān)聯(lián)支持?jǐn)?shù)組方式定義
5.0.5 增加延遲關(guān)聯(lián)預(yù)載入
5.0.5 一對一關(guān)聯(lián)預(yù)載入默認(rèn)采用IN查詢方式
5.0.4 一對一關(guān)聯(lián)支持JOIN和IN兩種方式預(yù)載入查詢

關(guān)聯(lián)查詢的預(yù)查詢載入功能,主要解決了N+1次查詢的問題,例如下面的查詢?nèi)绻?個記錄,會執(zhí)行4次查詢:

$list = User::all([1,2,3]);
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的profile模型數(shù)據(jù)
    dump($user->profile);
}

如果使用關(guān)聯(lián)預(yù)查詢功能,對于一對一關(guān)聯(lián)來說,只有一次查詢,對于一對多關(guān)聯(lián)的話,就可以變成2次查詢,有效提高性能。

$list = User::with('profile')->select([1,2,3]);
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的profile模型數(shù)據(jù)
    dump($user->profile);
}

支持預(yù)載入多個關(guān)聯(lián),例如:

$list = User::with('profile,book')->select([1,2,3]);

也可以支持嵌套預(yù)載入,例如:

$list = User::with('profile.phone')->select([1,2,3]);
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的phone模型
    dump($user->profile->phone);
}

V5.0.7版本以上,支持使用數(shù)組方式定義嵌套預(yù)載入,例如下面的預(yù)載入要同時獲取用戶的Profile關(guān)聯(lián)模型的Phone、JobImg子關(guān)聯(lián)模型數(shù)據(jù):

$list = User::with(['profile'=>['phone','job','img']])->select([1,2,3]);
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)
    dump($user->profile->phone);
    dump($user->profile->job);    
    dump($user->profile->img);    
}

可以在模型的get和all方法中使用預(yù)載入,和使用select方法是等效的:

$list = User::all([1,2,3],'profile,book');

如果要指定屬性查詢,可以使用:

$list = User::field('id,name')->with(['profile'=>function($query){$query->field('email,phone');}])->select([1,2,3]);
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的profile模型數(shù)據(jù)
    dump($user->profile);
}

關(guān)聯(lián)預(yù)載入名稱是關(guān)聯(lián)方法名,從V5.0.4+版本開始,支持傳入方法名的小寫和下劃線定義方式,例如如果關(guān)聯(lián)方法名是userProfileuserBook的話:

$list = User::with('userProfile,userBook')->select([1,2,3]);

等效于:

$list = User::with('user_profile,user_book')->select([1,2,3]);

V5.0.4+版本開始一對一關(guān)聯(lián)預(yù)載入支持兩種方式:JOIN方式(一次查詢)和IN方式(兩次查詢),如果要使用IN方式關(guān)聯(lián)預(yù)載入,在關(guān)聯(lián)定義方法中添加

<?php
namespace app\index\model;

use think\Model;

class User extends Model
{
    public function profile()
    {
    	// 設(shè)置預(yù)載入查詢方式為IN方式
        return $this->hasOne('Profile')->setEagerlyType(1);
    }
}

V5.0.5+版本開始,默認(rèn)使用IN查詢方式,如果需要改為JOIN查詢方式,使用

    	// 設(shè)置預(yù)載入查詢方式為JOIN方式
        return $this->hasOne('Profile')->setEagerlyType(0);

延遲預(yù)載入(V5.0.5+

有些情況下,需要根據(jù)查詢出來的數(shù)據(jù)來決定是否需要使用關(guān)聯(lián)預(yù)載入,當(dāng)然關(guān)聯(lián)查詢本身就能解決這個問題,因為關(guān)聯(lián)查詢是惰性的,不過用預(yù)載入的理由也很明顯,性能具有優(yōu)勢。

延遲預(yù)載入僅針對多個數(shù)據(jù)的查詢,因為單個數(shù)據(jù)的查詢用延遲預(yù)載入和關(guān)聯(lián)惰性查詢沒有任何區(qū)別,所以不需要使用延遲預(yù)載入。

如果你的數(shù)據(jù)集查詢返回的是數(shù)據(jù)集對象,可以使用調(diào)用數(shù)據(jù)集對象的load實現(xiàn)延遲預(yù)載入:

// 查詢數(shù)據(jù)集
$list = User::all([1,2,3]);
// 延遲預(yù)載入
$list->load('cards');
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的card模型數(shù)據(jù)
    dump($user->cards);
}

如果你的數(shù)據(jù)集查詢返回的是數(shù)組,系統(tǒng)提供了一個load_relation助手函數(shù)可以完成同樣的功能。

// 查詢數(shù)據(jù)集
$list = User::all([1,2,3]);
// 延遲預(yù)載入
$list = load_relation($list,'cards');
foreach($list as $user){
    // 獲取用戶關(guān)聯(lián)的card模型數(shù)據(jù)
    dump($user->cards);
}
文檔最后更新時間:2018-06-09 15:43:11

文檔
目錄

深色
模式

切換
寬度