關聯預載入
關聯預載入
版本 | 功能調整 |
---|---|
5.0.7 | 嵌套關聯支持數組方式定義 |
5.0.5 | 增加延遲關聯預載入 |
5.0.5 | 一對一關聯預載入默認采用IN查詢方式 |
5.0.4 | 一對一關聯支持JOIN和IN兩種方式預載入查詢 |
關聯查詢的預查詢載入功能,主要解決了N+1
次查詢的問題,例如下面的查詢如果有3個記錄,會執行4次查詢:
$list = User::all([1,2,3]);
foreach($list as $user){
// 獲取用戶關聯的profile模型數據
dump($user->profile);
}
如果使用關聯預查詢功能,對于一對一關聯來說,只有一次查詢,對于一對多關聯的話,就可以變成2次查詢,有效提高性能。
$list = User::with('profile')->select([1,2,3]);
foreach($list as $user){
// 獲取用戶關聯的profile模型數據
dump($user->profile);
}
支持預載入多個關聯,例如:
$list = User::with('profile,book')->select([1,2,3]);
也可以支持嵌套預載入,例如:
$list = User::with('profile.phone')->select([1,2,3]);
foreach($list as $user){
// 獲取用戶關聯的phone模型
dump($user->profile->phone);
}
V5.0.7
版本以上,支持使用數組方式定義嵌套預載入,例如下面的預載入要同時獲取用戶的Profile
關聯模型的Phone
、Job
和Img
子關聯模型數據:
$list = User::with(['profile'=>['phone','job','img']])->select([1,2,3]);
foreach($list as $user){
// 獲取用戶關聯
dump($user->profile->phone);
dump($user->profile->job);
dump($user->profile->img);
}
可以在模型的get和all方法中使用預載入,和使用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){
// 獲取用戶關聯的profile模型數據
dump($user->profile);
}
關聯預載入名稱是關聯方法名,從V5.0.4+
版本開始,支持傳入方法名的小寫和下劃線定義方式,例如如果關聯方法名是userProfile
和userBook
的話:
$list = User::with('userProfile,userBook')->select([1,2,3]);
等效于:
$list = User::with('user_profile,user_book')->select([1,2,3]);
V5.0.4+
版本開始一對一關聯預載入支持兩種方式:JOIN
方式(一次查詢)和IN
方式(兩次查詢),如果要使用IN
方式關聯預載入,在關聯定義方法中添加
<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
public function profile()
{
// 設置預載入查詢方式為IN方式
return $this->hasOne('Profile')->setEagerlyType(1);
}
}
V5.0.5+
版本開始,默認使用IN查詢方式,如果需要改為JOIN查詢方式,使用
// 設置預載入查詢方式為JOIN方式
return $this->hasOne('Profile')->setEagerlyType(0);
延遲預載入(V5.0.5+
)
有些情況下,需要根據查詢出來的數據來決定是否需要使用關聯預載入,當然關聯查詢本身就能解決這個問題,因為關聯查詢是惰性的,不過用預載入的理由也很明顯,性能具有優勢。
延遲預載入僅針對多個數據的查詢,因為單個數據的查詢用延遲預載入和關聯惰性查詢沒有任何區別,所以不需要使用延遲預載入。
如果你的數據集查詢返回的是數據集對象,可以使用調用數據集對象的load
實現延遲預載入:
// 查詢數據集
$list = User::all([1,2,3]);
// 延遲預載入
$list->load('cards');
foreach($list as $user){
// 獲取用戶關聯的card模型數據
dump($user->cards);
}
如果你的數據集查詢返回的是數組,系統提供了一個load_relation
助手函數可以完成同樣的功能。
// 查詢數據集
$list = User::all([1,2,3]);
// 延遲預載入
$list = load_relation($list,'cards');
foreach($list as $user){
// 獲取用戶關聯的card模型數據
dump($user->cards);
}
文檔最后更新時間:2018-06-09 15:43:11
未解決你的問題?請到「問答社區」反饋你遇到的問題