2014-09-23 77 views
14

我真的很想了解with()方法和load()方法之間的區別,但並不能真正理解。laravel with()方法與load()方法

正如我所見,使用with()方法是「更好」,因爲我渴望加載關係。看起來,如果我使用load()加載關係,就好像我將使用hasMany()(或任何其他與對象之間關係相關的方法)一樣。

我弄錯了嗎?

回答

32

兩者都完成了相同的最終結果 - 急切地將相關模型加載到第一個上。事實上,他們都運行完全相同的兩個查詢。主要區別在於with()在初始查詢(例如all(),first()find(x))後立即加載相關模型。當使用load()時,首先運行初始查詢,然後在稍後的某個時刻加載關係。

「渴望」在這裏是指我們對特定結果相關聯的所有相關模型只用一個查詢,而不是讓運行ñ查詢,其中ñ是項目的數量設置在最初的集合中。


如果我們急於負載使用with(),例如使用with()

預先加載:

$users = User::with('comments')->get(); 

......如果我們有5個用戶,下面的兩個查詢得到立即執行:

select * from `users` 
select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5) 

...並且我們最終得到了一系列附有用戶模型註釋的模型,因此我們可以執行類似於$users->comments->first()->body的操作。


「懶人」 使用預先加載load()

或者,我們可以先通過獲取初始結果這兩個查詢分開,:

$users = User::all(); 

它運行:

select * from `users` 

然後,如果我們決定我們需要所有這些用戶的相關評論,我們可以在事後急於加載它們:

$users = $users->load('comments'); 

它運行第二個查詢:

select * from `comments` where `comments`.`user_id` in (1, 2, 3, 4, 5) 

...我們結束了相同的結果,只需分成兩步。再次,我們可以致電$users->comments->first()->body去任何項目的相關模型。


爲什麼要用load()with()load()可讓您根據某些動態條件決定稍後是否需要運行第二個查詢。但是,如果沒有問題需要訪問所有相關項目,請使用with()。 (該文檔還引用一個緩存的好處是用負載(),但我不熟悉的,事實上,我相信load()結果不緩存。)


的替代品,替代這些將循環通過初始結果集並查詢每個項目的hasMany()關係。這將最終在此示例中運行n + 1查詢,或者。急於加載,無論是與with()或更高版本與load()預先完成,只運行查詢。

+0

謝謝!我仍然有一個問題,爲什麼我不使用急切加載然後使用正常的'hasMany()'方法? (我認爲對於我的答案的一個解決方案是,只要我只與一個用戶打交道,無論我是否使用熱切加載或無關緊要,因爲它會運行2個查詢呢?) – kfirba 2014-09-24 06:39:15

+1

這取決於什麼你正在處理的數據。如果您只對相關模型註釋感興趣,那麼在我們的示例中只需查詢'hasMany()'關係方法:'$ users = User :: find(1) - > comments;',它將僅返回信息關於評論,而不是用戶。但是,如果您還需要從初始模型(用戶)訪問數據,則需要使用('comments') - > get();然後使用$ user = User :: where('id','1') - >。 '會給你一個集合,包括來自用戶表的數據*和*他們的相關評論。無論哪種方式,都會運行2個相同的查詢,但結果集合是不同的。 – damiani 2014-09-24 12:33:53

+0

可以'load'像'with'一樣嵌套嗎?像這裏 - https://stackoverflow.com/questions/47048804/get-related-data-through-relation – Blagoh 2017-11-19 04:32:47