laravel 5.5 -- Eloquent 入门

柴亦
2023-12-01

快速入门

定义模型

php artisan make:model User --migration # 创建一个模型,并且创建他的迁移文件
// 等同于
php artisan make:model User -m
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Flight extends Model {
    /**
     * 与模型关联的数据表
     *
     * @var string
     */
    protected $table = 'my_flights'; // 默认 flights 
    protected $primaryKey = 'student_id'; // 默认 id
    public $incrementing = false; // 当你的主键不是自增或不是int类型
    public $timestamps = false; // 不自动维护created_at 和 updated_at 字段
    protected $dateFormat = 'U'; // 自定义自己的时间戳格式
    protected $connection = 'connection-name'; // 为模型指定不同的连接

    const CREATED_AT = 'creation_date'; // 自定义用于存储时间戳的字段名
    const UPDATED_AT = 'last_update'; // 同上
}

取模型

use App\Flight;
$flights = App\Flight::all();
foreach ($flights as $flight) {
    echo $flight->name;
}
# 每个 Eloquent 模型都可以当作一个 查询构造器
$flights = App\Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();

集合

https://docs.golaravel.com/docs/5.4/eloquent-collections/#available-methods

分块结果

$flights = $flights->reject(function ($flight) {
    return $flight->cancelled;
});

Flight::chunk(200, function ($flights) {
    foreach ($flights as $flight) {
        //
    }
});
使用游标

cursor 允许你使用游标来遍历数据库数据,一次只执行单个查询。在处理大数据量请求时 cursor 方法可以大幅度减少内存的使用:

foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
    //
}

取回单个模型/集合

$flight = App\Flight::find(1);

$flight = App\Flight::where('active', 1)->first();
$flights = App\Flight::find([1, 2, 3]);
未找到 异常

findOrFail 以及 firstOrFail 方法会取回查询的第一个结果。如果没有找到相应结果,则会抛出一个 Illuminate\Database\Eloquent\ModelNotFoundException

$model = App\Flight::findOrFail(1);

$model = App\Flight::where('legs', '>', 100)->firstOrFail();

如果该异常没有被捕获,则会自动返回 HTTP 404 响应给用户,因此当使用这些方法时,你没有必要明确的编写检查来返回 404 响应:

Route::get('/api/flights/{id}', function ($id) {
    return App\Flight::findOrFail($id);
});

// 聚合函数返回标量值
$count = App\Flight::where('active', 1)->count();
$max = App\Flight::where('active', 1)->max('price');

添加和更新模型

    public function store(Request $request)
    {
        // 验证请求...

        $flight = new Flight;

        $flight->name = $request->name;

        $flight->save();
    }
# 批量更新
App\Flight::where('active', 1)
          ->where('destination', 'San Diego')
          ->update(['delayed' => 1]);
# 当通过“Eloquent”批量更新时,saved和updated模型事件将不会被更新后的模型代替。这是因为批量更新时,模型从来没有被取回。

批量赋值

要先在你的模型上定义一个 fillableguarded 属性

protected $fillable = ['name']; # name 可以赋值
$flight = App\Flight::create(['name' => 'Flight 10']);
# 或者已有实例
$flight->fill(['name' => 'Flight 22']);

$guarded 属性应该包含一个你不想要被批量赋值的属性数组

用的时候应该只选择 $fillable$guarded 中的其中一个。

protected $guarded = ['price'];
# 除了 price 所有的属性都可以被批量赋值
# 如果你想让所有的属性都可以被批量赋值,你应该定义 $guarded为空数组。
protected $guarded = [];

firstOrNew 、 firstOrCreate、updateOrCreate

firstOrCreate 等价于 firstOrNew + save()

$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);

$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
);
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.

删除模型

$flight = App\Flight::find(1); // 取回模型再删除
$flight->delete();
// 或者
App\Flight::destroy(1);     // 直接删除
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(1, 2, 3);

$deletedRows = App\Flight::where('active', 0)->delete();

当使用 Eloquent 批量删除语句时,deletingdeleted 模型事件不会在被删除模型实例上触发。因为删除语句执行时,不会检索回模型实例。

软删除

<?php

namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model {
    use SoftDeletes;
    protected $dates = ['deleted_at'];
}
# 创建字段
Schema::table('flights', function ($table) {
    $table->softDeletes();
});

启用软删除的模型时,被软删除的模型将会自动从所有查询结果中排除。

#要确认指定的模型实例是否已经被软删除
if ($flight->trashed()) {
    //
}
查询包含被软删除的模型
$flights = App\Flight::withTrashed()
                ->where('account_id', 1)
                ->get();

# withTrashed 方法也可以被用在 关联 查询:
$flight->history()->withTrashed()->get();

onlyTrashed 会只取出软删除数据:

$flights = App\Flight::onlyTrashed()
                ->where('airline_id', 1)
                ->get();
恢复软删除的模型
$flight->restore();

App\Flight::withTrashed()
        ->where('airline_id', 1)
        ->restore();

$flight->history()->restore(); // 可以被用在 关联 查询
永久删除模型
// 强制删除单个模型实例...
$flight->forceDelete();

// 强制删除所有相关模型...
$flight->history()->forceDelete();

全局作用域

# 可以自由在  app 文件夹下创建 Scopes 文件夹来存放
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class AgeScope implements Scope {
    public function apply(Builder $builder, Model $model) {
        return $builder->where('age', '>', 200);
    }
}

# 需要重写给定模型的 boot 方法并使用  addGlobalScope 方法
<?php
namespace App;
use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
    protected static function boot() {
        parent::boot();

        static::addGlobalScope(new AgeScope);
    }
}
# 添加作用域后,如果使用 User::all() 查询则会生成如下SQL语句:
select * from `users` where `age` > 200
匿名全局作用域
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class User extends Model {
    protected static function boot() {
        parent::boot();

        static::addGlobalScope('age', function(Builder $builder) {
            $builder->where('age', '>', 200);
        });
    }
}
移除全局作用域
# 我们还可以通过以下方式,利用 age 标识符来移除全局作用:
User::withoutGlobalScope('age')->get();
# 移除指定全局作用域
User::withoutGlobalScope(AgeScope::class)->get();
# 移除几个或全部全局作用域
User::withoutGlobalScopes()->get();
User::withoutGlobalScopes([FirstScope::class, SecondScope::class])->get();

本地作用域

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
    /**
     * 限制查询只包括受欢迎的用户。
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePopular($query) {
        return $query->where('votes', '>', 100);
    }

    /**
     * 限制查询只包括活跃的用户。
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeActive($query) {
        return $query->where('active', 1);
    }
}
# 在进行方法调用时不需要加上 scope 前缀
$users = App\User::popular()->active()->orderBy('created_at')->get();
动态范围
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
    /**
     * 限制查询只包括指定类型的用户。
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeOfType($query, $type) {
        return $query->where('type', $type);
    }
}

现在,你可以在范围调用时传递参数:

$users = App\User::ofType('admin')->get();

事件

creating, created, updating, updated, saving, saved, deleting, deleted,  restoring, restored.

当一个新模型被初次保存将会触发 creating 以及 created 事件。如果一个模型已经存在于数据库且调用了 save 方法,将会触发 updatingupdated 事件。在这两种情况下都会触发 savingsaved 事件。

<?php

namespace App;

use App\Events\UserSaved;
use App\Events\UserDeleted;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 模型的时间映射。
     *
     * @var array
     */
    protected $events = [
        'saved' => UserSaved::class,
        'deleted' => UserDeleted::class,
    ];
}
<?php

namespace App\Observers;

use App\User;

class UserObserver
{
    /**
     * 监听用户创建的事件。
     *
     * @param  User  $user
     * @return void
     */
    public function created(User $user)
    {
        //
    }

    /**
     * 监听用户删除事件。
     *
     * @param  User  $user
     * @return void
     */
    public function deleting(User $user)
    {
        //
    }
}
<?php

namespace App\Providers;

use App\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 运行所有应用.
     *
     * @return void
     */
    public function boot()
    {
        User::observe(UserObserver::class);
    }

    /**
     * 注册服务提供.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}
 类似资料: