Laravel Eloquent 模型 使用技巧

1,919 阅读2分钟

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

最近一直在更新PHP相关的文章,前几篇总结编码规范和设计思想类的文章也是以PHP语言在举例子。

前几篇大家的反馈还不错,有人文有没有Java的demo,还有人评论说:php的文章不多了、你竟然还在用PHP...等等

在我上几篇文章底部的相关推荐里,也看了一篇介绍PHP框架的文章,那篇作者主要使用TP框架,我主要使用Laravel框架,所以我的代码Demo和设计思想和Laravel多多少少会有些关系。

那篇有句话是这样说的:PHP的优势是简单易学,因为简单易学导致从业者素质良莠不齐 , 我再补充一句:因为简单易学,没有强规范,导致初学者入门代码拖了PHP的后腿

PHP没有网传的那么糟糕,当然Go、Python、Java确实有比PHP有优势的地方,但是PHP仍然以简单易学,社区强大等优势在江湖中占有一席之地。

电影《霍元甲》:天下武功没有高下之分,只是习武之人有强弱之别。

技术圈子也是这种江湖吧~

目前我仍然是PHP,尤其是Laravel的支持者和推广者。

Laravel Eloquent 模型使用技巧

query ()

  1. 使用 query() 在PhpStorm这类IDE中会自动补全方法
  2. 使用 query() 能简化代码逻辑,实现更优雅

举例

不使用query

 if($status && $type) {
 $users = User::where('status', $status)->where('type', $type)->latest()->get();
 } else if ($status) {
 $users = User::where('status', $status)->latest()->get(); 
 } else if ($type) {
 $users = User::where('status', $type)->latest()->get();
 } else {
 $users = User::latest()->get(); 
 }

使用query

 $query = User::query();
 if ($status) {
  $query->where('status', $status);
 }
 if ($type) {
  $query->where('type', $type);
 } 
 $users = $query->latest()->get();

复用或克隆 query ()

上面的栗子介绍了 query 的使用,下面介绍一种特殊情况,需要我们注意:有时候需要克隆 query()

场景:获取今天创建的已激活和未激活的产品

$query = Product::query();

$today = request()->date ?? today();

if($today){
    $query->where('created_at', $today);
}

//获取已激活和未激活的产品

$active_products = $query->where('status', 1)->get(); // 这一行修改了 $query 对象变量

$inactive_products = $query->where('status', 0)->get(); // 所以这里我们不会找到任何未激活的产品

$inactive_products没有按期望渠道值,因为$query的值在每次执行时都会改变。 上述查询语句转成sql相当于是

where status = 1 and startus = 2

为了解决这个问题,我们可以通过复用这个 $query 对象来进行多次查询。

我们可以通过克隆这个 $query 来解决问题,如下:

$active_products = (clone $query)->where('status', 1)->get(); // 它不会修改 $query

$inactive_products = (clone $query)->where('status', 0)->get(); // 所以我们将从 $query 中获取未激活的产品

Eloquent where 日期方法

在 Eloquent 中,使用 whereDay()whereMonth()whereYear()whereDate() 和 whereTime() 函数检查日期。

非常的灵活,同时强力安利 Carbon

$products = Product::whereDate('created_at', '2020-01-31')->get();

$products = Product::whereMonth('created_at', '11')->get();

$products = Product::whereDay('created_at', '28')->get();

$products = Product::whereYear('created_at', date('Y'))->get();

$products = Product::whereTime('created_at', '=', '19:23:18')->get();

增量和减量

如果要增加数据库某个表中的某个列,只需使用 increment() 函数。你不仅可以增加 1,还可以增加一些数字,比如 50。

减量使用decrement()函数,使用方式和增量一致。

Post::find($post_id)->increment('view_count');

User::find($user_id)->increment('points', 50);

Post::find($post_id)->decrement('comment_count');

User::find($user_id)->decrement('fans_count', 50);

定义 timestamp 列

如果数据库表不包含 timestamp 字段 created_at 和 updated_at,可以使用 $timestamps = false 属性指定 Eloquent 模型不使用它们。

class Company extends Model
{
    public $timestamps = false;
}

也可以指定timestamp字段,使用其他字段代替 created_at 和 updated_at

class Company extends Model
{
    public $timestamps = true;
    
    const CREATED_AT = 'createtime';
    const UPDATED_AT = 'updatetime';
}

模型 all:列

当调用 Eloquent 的 Model::all() 时,可以指定要返回的列。

$users = User::all(['id', 'name', 'sex']);

失败或不失败

除了 findOrFail() 之外,还有 Eloquent 方法 firstOrFail(),如果没有找到查询记录,它将返回 404 页。

$user = User::where('email', 'ucenter@juejin.cn')->firstOrFail();

欢迎互动

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