将 Symfony 查询转换为 Laravel 6.x Eloquent 查询
Convert Symfony Query to Laravel 6.x Eloquent Query
我目前正在将 Symfony 3.4 站点迁移到 Laravel 6.x,我正在寻找将此查询转换为 Laravel Eloquent 查询的正确方法。
这是 Symfony 查询
$qb = $this->createQueryBuilder('up');
$qb->select('COUNT(up.id)');
$qb->leftJoin('up.workout', 'w')
->leftJoin('up.user', 'u')
->where('up.parent IS NULL AND up.deleted = false')
->andWhere('up.status != \'Just started\' OR up.status is NULL')
->andWhere('w.workoutType = \'Normal\' AND u.deleted = false')
// Long Cardio, Long Cardio (Burn) and Long Cardio (Hardcore)
->andWhere('up.completed = true OR (up.completed_cardio_shred = true AND ((w.level = \'Long Cardio\') OR (w.level = \'Long Cardio (Burn)\') OR (w.level = \'Long Cardio (Hardcore)\')))');
$qb->getQuery()->getSingleScalarResult();
这是我使用 Laravel 6.x 数据库查询
生成的
$userProgressTable = DB::table('user_progress');
$userProgressTable->select('id');
$userProgressTable->leftJoin('fos_user', 'fos_user.id', '=', 'user_progress.user_id');
$userProgressTable->leftJoin('workout', 'workout.id', '=', 'user_progress.workout_id');
$userProgressTable->whereRaw('user_progress.parent_id IS NULL');
$userProgressTable->where('user_progress.deleted', '=', false);
$userProgressTable->whereRaw('user_progress status <> \'Just started\' OR user_progress.status IS NULL');
$userProgressTable->where('workout.workout_type', '=', 'Normal');
$userProgressTable->where('user.deleted', '=', false);
$userProgressTable->whereRaw('user_progress.completed = true OR (user_progress.completed_cardio_shred = true AND ((workout.level = \'Long Cardio\') OR (workout.level = \'Long Cardio (Burn)\') OR (workout.level = \'Long Cardio (Hardcore)\'))');
$userProgressTable->where('user_progress.user_id', '=', $user->id);
return $userProgressTable->count();
我的问题是,如果我使用 Eloquent Model/Query 方式,上述查询会是什么样子?
首先,您必须自己拥有模型 类,并正确设置任何关系。从您分享的代码中,我看到了三个独立的模型。一般来说,每个 table 需要一个模型,但这也有点依赖于 table。例如,你不需要一个作为枢轴 table(但你可以有一个)。
class UserProgress extends Eloquent
{
...
}
class FosUser extends Eloquent
{
...
}
class workout extends Eloquent
{
...
}
您可以随意命名 类,它们不必与 table 名称匹配(有关详细信息,请参阅文档:https://laravel.com/docs/5.8/eloquent#eloquent-model-conventions)。
然后将您的关系添加到每个需要它们的模型 (https://laravel.com/docs/5.8/eloquent-relationships),然后您就可以开始查询了。它可能看起来像这样:
$result = UserProgress::join('fos_user', 'fos_user.id', '=', 'user_progress.user_id')
->join('workout', 'workout.id', '=', 'user_progress.workout_id')
->whereRaw('...')
...
->where('user_progress.user_id', '=', $user->id)
->get(); // this returns a Collection object
return $result->count(); // This is a Collection method
这只是一个示例,您可以通过多种方式构建 where 子句(where('user_id', '=', $user.id)
与 whereUserId($user.id)
等),但应该足以让您入门。
此外,对于这个特定的查询,您实际上只需要第一个模型,但您最终可能最终会使用其他两个 table 的模型。
我目前正在将 Symfony 3.4 站点迁移到 Laravel 6.x,我正在寻找将此查询转换为 Laravel Eloquent 查询的正确方法。
这是 Symfony 查询
$qb = $this->createQueryBuilder('up');
$qb->select('COUNT(up.id)');
$qb->leftJoin('up.workout', 'w')
->leftJoin('up.user', 'u')
->where('up.parent IS NULL AND up.deleted = false')
->andWhere('up.status != \'Just started\' OR up.status is NULL')
->andWhere('w.workoutType = \'Normal\' AND u.deleted = false')
// Long Cardio, Long Cardio (Burn) and Long Cardio (Hardcore)
->andWhere('up.completed = true OR (up.completed_cardio_shred = true AND ((w.level = \'Long Cardio\') OR (w.level = \'Long Cardio (Burn)\') OR (w.level = \'Long Cardio (Hardcore)\')))');
$qb->getQuery()->getSingleScalarResult();
这是我使用 Laravel 6.x 数据库查询
生成的 $userProgressTable = DB::table('user_progress');
$userProgressTable->select('id');
$userProgressTable->leftJoin('fos_user', 'fos_user.id', '=', 'user_progress.user_id');
$userProgressTable->leftJoin('workout', 'workout.id', '=', 'user_progress.workout_id');
$userProgressTable->whereRaw('user_progress.parent_id IS NULL');
$userProgressTable->where('user_progress.deleted', '=', false);
$userProgressTable->whereRaw('user_progress status <> \'Just started\' OR user_progress.status IS NULL');
$userProgressTable->where('workout.workout_type', '=', 'Normal');
$userProgressTable->where('user.deleted', '=', false);
$userProgressTable->whereRaw('user_progress.completed = true OR (user_progress.completed_cardio_shred = true AND ((workout.level = \'Long Cardio\') OR (workout.level = \'Long Cardio (Burn)\') OR (workout.level = \'Long Cardio (Hardcore)\'))');
$userProgressTable->where('user_progress.user_id', '=', $user->id);
return $userProgressTable->count();
我的问题是,如果我使用 Eloquent Model/Query 方式,上述查询会是什么样子?
首先,您必须自己拥有模型 类,并正确设置任何关系。从您分享的代码中,我看到了三个独立的模型。一般来说,每个 table 需要一个模型,但这也有点依赖于 table。例如,你不需要一个作为枢轴 table(但你可以有一个)。
class UserProgress extends Eloquent
{
...
}
class FosUser extends Eloquent
{
...
}
class workout extends Eloquent
{
...
}
您可以随意命名 类,它们不必与 table 名称匹配(有关详细信息,请参阅文档:https://laravel.com/docs/5.8/eloquent#eloquent-model-conventions)。
然后将您的关系添加到每个需要它们的模型 (https://laravel.com/docs/5.8/eloquent-relationships),然后您就可以开始查询了。它可能看起来像这样:
$result = UserProgress::join('fos_user', 'fos_user.id', '=', 'user_progress.user_id')
->join('workout', 'workout.id', '=', 'user_progress.workout_id')
->whereRaw('...')
...
->where('user_progress.user_id', '=', $user->id)
->get(); // this returns a Collection object
return $result->count(); // This is a Collection method
这只是一个示例,您可以通过多种方式构建 where 子句(where('user_id', '=', $user.id)
与 whereUserId($user.id)
等),但应该足以让您入门。
此外,对于这个特定的查询,您实际上只需要第一个模型,但您最终可能最终会使用其他两个 table 的模型。