Laravel Eloquent 模型 进阶技巧

797 阅读2分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

天下武功没有高下之分,只是习武之人有强弱之别。

上一篇介绍了 Laravel Eloquent 模型的基本使用技巧 Laravel Eloquent 模型 使用技巧 , 这篇介绍进阶技巧。

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']);

欢迎互动

欢迎大家点赞关注,大佬们有啥好的建议欢迎在评论区指教