Laravel 文档阅读:数据库之查询语句构造器(下篇)

orderBygroupBylimitoffset

orderBy

orderBy 方法指定结果数据按照某个字段的升序/降序排列。它的第一个参数是排序的字段名,第二个参数是排序方向(asc 或者 desc):

$users = DB::table('users')
                ->orderBy('name', 'desc')
                ->get();

latest / oldest

latest / oldest 方法实现字段按照日期便捷地排序。默认是依据 created_at 字段排序的,你也可以传递要排序的字段名以便覆盖默认设定:

$user = DB::table('users')
                ->latest()
                ->first();

$user = DB::table('users')
                ->latest('updated_at')
                ->first();

inRandomOrder

inRandomOrder 方法实现查询结果的乱序排列。例如,取得随意的一个用户信息:

$randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();

groupBy / having / havingRaw

groupByhaving 方法可以用来给查询结果进行分组。having 方法的签名类似 where 方法:

$users = DB::table('users')
                ->groupBy('account_id')
                ->having('account_id', '>', 100)
                ->get();

havingRaw 方法用来设置原生字符串到 having 子句中。例如,我们可以找到所有销售额大于 2500刀 的部门:

 $users = DB::table('orders')
                ->select('department', DB::raw('SUM(price) as total_sales'))
                ->groupBy('department')
                ->havingRaw('SUM(price) > 2500')
                ->get();

skip / take

限制从查询返回的结果数,或者在查询中跳过给定数量的结果。你可以使用 skiptake 方法:

$users = DB::table('users')->skip(10)->take(5)->get();

或者使用起到一样作用的 limitoffset 方法:

$users = DB::table('users')
                ->offset(10)
                ->limit(5)
                ->get();

条件子句

有时我们只想在某些条件成立的时候呢才去执行一些条件子句查询。比如,对于 where 子句,我们只想在输入数据里包含某个字段的时候,才去执行,那么这时就要用到 when 了。

$role = $request->input('role');

$users = DB::table('users')
                ->when($role, function ($query) use ($role) {
                    return $query->where('role_id', $role);
                })
                ->get();

在上面这段代码里,只有当闭包的第一个参数($role)判定为 true 时才会执行。如果第一个参数的判定值是 false,那么就不会执行闭包里的内容。

when 方法还接受第三个参数,跟第二个参数一样,也是一个闭包——当判定条件(第一个参数)为 false 时,就会执行这里的逻辑。为了说明这个方法的使用场景,我们来举一个配置默认使用的排序字段的例子:

$sortBy = null;

$users = DB::table('users')
                ->when($sortBy, function ($query) use ($sortBy) {
                    return $query->orderBy($sortBy);
                }, function ($query) {
                    return $query->orderBy('name');
                })
                ->get();

插入

查询语句构造器还提供一个 insert 方法用来项数据库插入数据。insert 方法接收一个包含字段键值组成的数组。

DB::table('users')->insert(
    ['email' => 'john@example.com', 'votes' => 0]
);

当然 insert 方法也支持同时插入多条数据:

DB::table('users')->insert([
    ['email' => 'taylor@example.com', 'votes' => 0],
    ['email' => 'dayle@example.com', 'votes' => 0]
]);

自增 ID

如果包含一个自增 ID,那么可以使用 insertGetId 来获得插入的记录的 ID 值:

$id = DB::table('users')->insertGetId(
    ['email' => 'john@example.com', 'votes' => 0]
);

更新

除了向数据库插入数据,查询语句构造器还提供了更新已存在记录的 update 方法。与 insert 方法类似, update 方法接收一个要更新的、包含字段键值组成的数组。

DB::table('users')
            ->where('id', 1)
            ->update(['votes' => 1]);

更新 JSON 字段类型

更新 JSON 字段类型,需要用到 -> 语法,不过这仅在支持 JSON 字段类型的数据库中有效。

DB::table('users')
            ->where('id', 1)
            ->update(['options->enabled' => true]);

Increment / Decrement

查询语句构造器也提供了用来增加/减少某个字段值的方法 increment / decrement。这只是一个语法糖,与手动编写 update 语句相比,提供了更具表现力和简洁的 API。

DB::table('users')->increment('votes');

DB::table('users')->increment('votes', 5);

DB::table('users')->decrement('votes');

DB::table('users')->decrement('votes', 5);

这两个方法都至少接受一个参数,那就是要修改的字段。第二个控制增加/减少的数量,默认是 1

当然,我们还可以额外的提供其他要修改的字段:

DB::table('users')->increment('votes', 1, ['name' => 'John']);

删除

使用 delete 方法从数据库表删除记录,可以在使用时用 where 子句来添加约束条件:

DB::table('users')->delete();

DB::table('users')->where('votes', '>', 100)->delete();

如果要清空整张表——删除所有数据、将自动递增主键 ID 设置为 0,那么就要用 truncate 方法:

DB::table('users')->truncate();

悲观锁

「悲观锁」作用在 select 语句上,如果要使用「共享锁」运行语句,可以在查询上使用 sharedLock 方法。共享锁可以保证用户 在读取数据时,除非事务提交,否则 数据不会被修改

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

还有一个 lockForUpdate 方法,比 sharedLock 还厉害——可以保证用户 在读取数据时,保证数据不被修改或被另一个共享锁所选择

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 3年前 加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 2
$randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();

这个采用的 sql 这样吗select *from users order by rand() limit 1;性能会慢

3年前 评论

@mingyun 是产生这样的语句

select * from `users` order by RAND() limit 1  

这里是方法使用介绍,主要是为了说明方法的使用方式。至于性能问题,如果用户表数据量巨大,可以考虑使用 select 子句或者索引来提升查询性能。

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!