Laravel 5 Laravel雄辩,在单个查询中选择具有关系的模型
假设我们对车型和驾驶员有多对多关系:Laravel 5 Laravel雄辩,在单个查询中选择具有关系的模型,laravel-5,eloquent,Laravel 5,Eloquent,假设我们对车型和驾驶员有多对多关系: class Car extends Model {...} class Connection extends Model { public function car() { return $this->belongsTo('app\Car'); } public function driver() { return $this->belongsTo('App\Driver
class Car extends Model {...}
class Connection extends Model
{
public function car()
{
return $this->belongsTo('app\Car');
}
public function driver()
{
return $this->belongsTo('App\Driver');
}
}
class Driver extends Model {...}
现在我想查询一下约翰可以驾驶的汽车。对于QueryBuilder,这非常简单:
$query = DB::table('cars')
->join('connections', 'cars.id', '=', 'connections.car_id')
->join('drivers', 'connection.driver_id', '=', 'drivers.id')
->where('drivers.name', 'like', 'John')->select('cars.*')->get();
这将生成一个SQL查询,这或多或少是我所期望的
应用程序的其余部分使用Eloquent进行数据库查询,因此我想用Eloquent重写这一部分。我对它进行了多次尝试,但我无法生成一个包含普通联接(而不是子查询)的查询。可能吗 您可以使用belongToMany关系并删除您的连接模型
将您的模型更改为:
class Car extends Model
{
public function drivers()
{
return $this->belongsToMany(Driver::class, 'connection');
}
}
class Driver extends Model
{
public function cars()
{
return $this->belongsToMany(Car::class, 'connection');
}
}
并通过以下方式查询驾驶员的车辆:
$drivers = Driver::with('cars')
->where('name', 'like', 'John')
->get();
foreach ($drivers as $driver) {
$cars = $driver->cars;
}
另一个小优化是遵循Laravel关于表命名的约定,并将连接表调用为car_driver,这样您就可以从belongstomy方法中删除第二个参数。您可以使用where has elought函数来获取可以由John驾驶的汽车
$cars = Car::whereHas('drivers',function($query) use ($driver_name){
$query->where('name','like','%'.$driver_name.'%');
})->get();
对于模型,您可以使用@Idob写在其答案中的模型。我不能使用belongstomy,因为我的连接模型比上面示例中的模型稍微复杂一些。我检查了你的代码,它工作正常,但效率低下;Laravel展示了执行的两个查询。另外,在您的示例中,您首先调用,但如果我使用所有名为John的驱动程序,则生成的查询将变得更加低效,因为id位于…我已更新为查询以支持多个驱动程序,请检查它。对于你提到的效率低下——没错,这是两个问题,而不是一个问题。一般来说,ORM的效率不如编写自己的查询,但您得到的好处是值得的。所以,除非这是一个每天点击数千万次的页面,否则我会坚持使用ORM&Elotent。我明白了,因此得出结论:实际上没有办法有一个且只有一个查询。是吗?因为每个雄辩的模型都充当一个查询生成器,所以您可以调用Car类而不是DB,并删除表“cars”,但它是同一个查询生成器,所以这并不重要。