Laravel Eloquent 模型使用进阶技巧
列名重命名
在 Eloquent Query Builder 中,可以使用 as 重命名列名称进行输出,比如:
$users = DB::table('users')->select('name', 'email as my_email')->get();
Map 查询结果
在 Eloquent 查询之后,可以使用 Collections 中的 map() 函数来修改行。
$users = User::where('role_id', 1)->get()->map(function (User $user) { $user->some_column = some_function($user); return $user; });
这里在对比一下 数组array 的map()用法:
$userIds = array_map(function ($value) { return ['userid' => $value]; }, $appointmentsUserIds); 返回的数据是 [['userid'=xxxx],['userid'=xxxx],]
根据时间字段快速排序
不建议使用:
User::orderBy('created_at', 'desc')->get();
建议使用下述方法执行效率更快:
User::latest()->get();
默认情况下,latest() 会按 created_at 降序排序。
有一个相反的方法 oldest(),它按 created_at 升序排序:
User::oldest()->get();
可以指定时间字段进行排序
$lastUpdatedUser = User::latest('updated_at')->first();
原始SQL查询
使用类似 whereRaw() 方法的 SQL 原始查询,直接在查询中进行一些特定于数据库的计算,而不是在 Laravel 中,通常结果会更快。
例如,获得注册后 10 天以上仍处于活跃状态的用户,可以使用以下代码:
User::where('active', 1) ->whereRaw('TIMESTAMPDIFF(DAY, created_at, updated_at) > ?', 10) ->get();
多个范围查询
在 Eloquent 中组合和链式查询范围,在查询中使用多个范围。
模型:
public function scopeActive($query) { return $query->where('active', 1); } public function scopeRegisteredWithinDays($query, $days) { return $query->where('created_at', '>=', now()->subDays($days)); }
控制器中使用:
$users = User::registeredWithinDays(10)->active()->get();
无需转换 Carbon
如果使用 whereDate() 查询今日的记录,可以直接使用 Carbon 的 now() 方法,会自动转换为日期进行查询,无需指定 ->toDateString():
// 今日注册的用户 $todayUsers = User::whereDate('created_at', now()->toDateString())->get(); // 无需 toDateString() ,直接 now() 即可 $todayUsers = User::whereDate('created_at', now())->get();
永不更新某个字段
如果有一个数据库字段需要只更新一次,可以使用 Eloquent 的修改器来实现:
class User extends Model { public function setEmailAttribute($value) { //有值则不设置 if ($this->email) { return; } $this->attributes['email'] = $value; } }
find () 查询多条数据
find() 不止可以查询一条数据,当传入多个 ID 的值会返回这些结果的集合:
// 返回 Eloquent Model $user = User::find(1); // 返回 Eloquent Collection $users = User::find([1,2,3]);
find () 限制字段
find() 可在查询多条的数据的情况下,指定只返回哪些字段:
// 会返回只包含 first_name 和 email 的 Eloquent 模型 $user = User::find(1, ['first_name', 'email']); // 会返回只包含 first_name 和 email 两个字段的 Eloquent 集合 $users = User::find([1,2,3], ['first_name', 'email']);