将Laravel查询转换为Eager Loading

时间:2014-12-13 13:20:32

标签: php laravel eager-loading

我一直在倾向于Laravel并且尝试实现某些东西而且我做了,它有效,但我听说可以使用Eager Loading以更简单的方式做同样的事情。

想象一下,我们有4个表:garagescarssecuritiesplaces

garages是您可以找到cars的地方,securities是保证汽车安全在车库内的安全措施,places是您可以找到的地方车库类似于那个。

我想要的是列出garages并加入三个carssecuritiesplaces这样的表:

Garage 1 has 2 cars with 3 securities and has 3 more garages similar
Garage 2 has 1 cars with 1 securities and has 2 more garages similar

以下是查询:

select 
    g.garage_name, 
    count(distinct c.car_id) as count_cars,
    count(distinct s.security_id) as count_securities,
    count(distinct p.place_id) as count_places
from garages g
left join cars c on c.garage_id = g.garage_id
left join securities s on s.car_id = c.car_id
left join places p on p.garage_id = g.garage_id
group by g.garage_name
order by g.garage_name;

它正常工作,你可以看到here

我将其转换为:

$garages = Garages::select('garage_name',
DB::raw('count(distinct cars.car_id) as count_cars'),
DB::raw('count(distinct securities.security_id) as count_securities'),
DB::raw('count(distinct places.place_id) as count_places'))
->leftJoin('cars', 'cars.garage_id', '=', 'garages.garage_id')
->leftJoin('securities', 'securities.car_id', '=', 'cars.car_id')
->leftJoin('places', 'places.garage_id', '=', 'garages.garage.id')
->groupBy('garages.garage_name')
->orderBy('garages.garage_name')
->get();

正如我上面所述,它正在运行,但我想知道是否有一种更简单的方法可以使用Eager Loading以及如何转换?

  • 当我说更容易时,我的意思是更具可读性,分离性,正确的方式,而不是那个大问题。

1 个答案:

答案 0 :(得分:3)

假设您确实拥有实体的4个Eloquent Model类。 如果是这种情况,您可以尝试通过Eloquent ORM进行预先加载。

$Garages = Garage::with(['cars','places', 'securities'])->get();

然后,您可以根据需要使用返回的结果集(Illuminate \ Support \ Collection)准备必要的输出。您可以按照自己喜欢的方式转换集合中的项目。这是一个例子。

在你的情况下,我假设这是做这件事的方法。

$Garages->transform(function($garage) {
   return array(
       'garage_name' => $garage->garage_name,
       'count_cars' => $garage->cars->count(),
       'count_securities' => $garage->securities->count(),
       'count_places' => $garage->places->count(),
       // add as many custom details you want here
   );
});

return $Garages->toArray(); // see the output

现在我希望你明白了。

请记住,您的模型类文件应该具有关系。它应该如下所示。

class Garage extends Eloquent {

   public function cars() {
     return $this->hasMany('Car');
   }

   public function securities()
   {
     return $this->hasMany('Security');
   }

   public function places()
   {
     return $this->hasMany('Place');
   }

}

class Car extends Eloquent {

  // relationships here
}

class Security extends Eloquent {

  // relationships here
}

class Place extends Eloquent {

  // relationships here
}

这只是一个帮助您理解的简单示例。

享受! :d