はじめに
PHP及びLaravelの勉強中。
参考URL : https://readouble.com/laravel/9.x/ja/eloquent-relationships.html
設定
- Categoryモデル(カテゴリーモデル)とItemモデル(商品モデル)が1対多の関係性で存在
- Categoryモデル側 -> hasMany
- Itemモデル側 -> belongsTo
- Itemモデル(商品モデル)とStockモデル(在庫モデル)が1対1の関係性で存在
- Itemモデル側 -> hasOne
- Stockモデル側 -> belongsTo
本文
通常、リレーション先へのプロパティアクセスはLazyロードされる。(N+1問題)
上記の問題を解決するのがEagerロード
-> 使用すればアプリケーションのパフォーマンスが向上
例 : 全ての商品のカテゴリー名を取得したい時
// ⑴ Lazyロード
$items = Item::query()->get();
foreach($items as $item){
echo $item->category->name;
}
// ⑵ Eagerロード
$items = Item::query()->with('category')->get();
foreach($items as $item){
echo $item->category->name;
}
出力結果は同じだが、⑴はクエリが商品の数だけ発行される(100個商品あれば100回)。
⑵ではクエリの発行回数は2回だけ。(すべての商品取得とすべての商品のカテゴリ取得)
様々なパターン
複数のリレーション先の取得
$items = Item::query()->with(['category', 'stock'])->get();
リレーション先のリレーション先の取得
$categories = Category::query()->with('items.stock')->get();
特定のカラムのみの取得(関連する外部キー、idは必ず必要)
$items = Item::query()->with('category:id,name')->get();
$items = Item::query()->with('stock:item_id,stock')->get();
クエリ条件の追加
$items = Item::query()->with(['stock' => function ($query) {
$query->where('stock', '>', 300);
}])->get();