Laravel中的Eloquent(ORM)的工做方式很使人驚訝,並提供訪問數據庫的很是簡單的方法。在本文中,咱們將瞭解Laravel Eloquent中的懶加載和即時加載以及它如何在後臺運行。php
第一步咱們須要定義模型之間的關係的。在這個例子中,我將使用兩個模型,house
和 city
。房子屬於一個城市,城市有不少房屋。讓咱們看看模型 House
的關係:sql
class House extends Model { protected $fillable = [ 'title', 'description', 'price' ]; public function city() { return $this->belongsTo('App\City'); } }
注意:對於多對一的關係(房子屬於一個城市),函數名稱是單數。 [
public function city()
]數據庫
class City extends Model { protected $fillable = [ 'name', 'code' ]; public function houses() { return $this->hasMany('App\House'); } }
注意:對於一對多關係(城市有不少房屋),函數名稱是複數。 [
public function houses()
]函數
$houses = House::all();
默認狀況下,在Eloquent中訪問數據是「懶加載」,在上面的代碼中,咱們獲取了全部數據在內部表中,實際執行的SQL查詢是:this
select * from `houses`
在這一步中,關係表(城市)中的數據尚未被獲取,若是咱們想訪問關係表中的數據,咱們能夠像這樣訪問:code
foreach ($houses as $house) { echo $house->city->name; // 這就是懶加載 }
實際執行的SQL查詢是ip
select * from `cities` where `cities`.`id` = ? limit 1 select * from `cities` where `cities`.`id` = ? limit 1 select * from `cities` where `cities`.`id` = ? limit 1 ...
該過程將循環房屋內的全部記錄,併爲每一個循環執行1次查詢以獲取城市數據,例如咱們有20個房屋記錄,查詢獲取關係表中的數據將執行20次+1原始查詢獲取 房屋數據,查詢「延遲加載」的時間是N + 1。ci
有時在應用程序中使用即時加載很是有用,例如,你正在使用Ajax調用數據,在這種狀況下,咱們必須使用預加載來準備在關係表中包含數據的全部數據,而後再將結果返回給Ajax。 要使用即時加載,只需在獲取數據時使用 with
方法。get
$houses = House::with('city')->get();
如今全部的房屋數據和在關係表中的數據都同時加載出來了,查詢的SQL語句的是it
select * from houses select * from cities where id in (1, 2, 3, 4, 5, ...)
使用即時加載時僅執行2個查詢。 正如你能夠看到上面的查詢,一個查詢是在房屋表中獲取全部數據,另外一個查詢是獲取城市表中的全部數據,使用IN操做將ID與房屋表中的city_id匹配。
在某些狀況下,這對於即時動態加載很是有用,咱們能夠決定是否須要加載關係表中的數據。
$houses = House::all(); if($isLoad) { $houses->load('city'); // 對應 house model中的 city 方法 }
咱們可使用 load
方法在特定條件下加載關係表中的數據。
這一點很是有用,實際中你們能夠多試試。
如今你理解了這個過程,但願它能幫助你理解懶加載和即時加載的用法和基本原理。
更多PHP知識,能夠前往PHPCasts