一、基础使用
如何定义模型和使用artisan命令来创建模型、以及在创建模型的时候生成数据库迁移文件
// 定义一个 Eloquent 模型
class User extends Model {
}
// 生成一个 Eloquent 模型
php artisan make:model User
// 生成一个 Eloquent 模型的时候,顺便生成迁移文件
php artisan make:model User --migration OR -m
// 指定一个自定义的数据表名称
class User extends Model {
protected $table = 'my_users';
}
二、More
// 创建一条数据
Model::create(array('key' => 'value'));
// 通过属性找到第一条相匹配的数据或创造一条新数据
Model::firstOrCreate(array('key' => 'value'));
// 通过属性找到第一条相匹配的数据或实例化一条新数据
Model::firstOrNew(array('key' => 'value'));
// 通过属性找到相匹配的数据并更新,如果不存在即创建
Model::updateOrCreate(array('search_key' => 'search_value'), array('key' => 'value'));
// 使用属性的数组来填充一个模型, 用的时候要小心「Mass Assignment」安全问题 !
Model::fill($attributes);
// 通过主键删除模型
// 在上面的例子中,在调用 delete 之前需要先去数据库中查找对应的模型。
// 事实上,如果你知道了模型的主键,你可以直接使用 destroy 方法来删除模型,而不用先去数据库中查找。
// destroy 方法除了接受单个主键作为参数之外,还接受多个主键,或者使用数组,集合来保存多个主键
Model::destroy(1);
Model::destroy(1, 2, 3);
Modelt::destroy([1, 2, 3]);
Model::destroy(collect([1, 2, 3]));
// Eloquent 的 all 方法会返回模型中所有的结果
Model::all();
// 检索单个模型 / 集合
// 除了从指定的数据表检索所有记录外,你可以使用 find 或 first 方法来检索单条记录。这些方法返回单个模型实例,而不是返回模型集合
Model::find(1);
// 使用双主键进行查找
Model::find(array('first', 'last'));
// 查找失败时抛出异常
Model::findOrFail(1);
// 使用双主键进行查找, 失败时抛出异常
Model::findOrFail(array('first', 'last'));
// 获取所有数据 (使用 get 方法获取结果)
Model::where('foo', '=', 'bar')->get();
// 查询一条数据(从数据表中获取单行或单列)
Model::where('foo', '=', 'bar')->first();
// 除了通过 count 方法可以确定查询条件的结果是否存在之外,还可以使用 exists 和 doesntExist 方法
Model::where('foo', '=', 'bar')->exists();
// 动态属性查找
Model::whereFoo('bar')->first();
// 查找失败时抛出异常
Model::where('foo', '=', 'bar')->firstOrFail();
// 快速复制当前的数据,记得用 save 保存。
Model::find(1)->replicate()->save();
// 聚合方法
Model::where('foo', '=', 'bar')->count();
// 删除where条件中所有数据
Model::where('foo', '=', 'bar')->delete();
// 输出原始的查询语句
Model::where('foo', '=', 'bar')->toSql();
Model::whereRaw('foo = bar and cars = 2', array(20))->get();
Model::on('connection-name')->find(1);
Model::with('relation')->get();
Model::all()->take(10);
Model::all()->skip(10);
// 默认的 Eloquent 排序是上升排序
Model::all()->orderBy('column');
Model::all()->orderBy('column','desc');
//针对Time排序(默认使用 created_at 列作为排序)
Model::all()->latest();
Model::all()->oldest();
// 查询 json 数据
Model::where('options->language', 'en')->get(); # 字段是字符串
Model::whereJsonContains('options->languages', 'en')->get(); # 字段是数, 使用 whereJsonContains 来查询 JSON 数组
Model::whereJsonLength('options->languages', 0)->get(); # 字段长度为 0, 使用 whereJsonLength 来查询 JSON 数组的长度
Model::whereJsonDoesntContain('options->languages', 'en')->get(); # 字段是数组, 不包含
三、软删除
一般除了真实删除数据库记录, Eloquent 也可以「软删除」模型。软删除的模型并不是真的从数据库中删除了。事实上,是在模型上设置了 deleted_at 属性并将其值写入数据库。如果 deleted_at 值非空,代表这个模型已被软删除。如果要开启模型软删除功能,你需要在模型上使用 Illuminate\Database\Eloquent\SoftDeletes trait:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
use SoftDeletes;
}
查询软删除模型
// 包括已软删除的模型
Model::withTrashed()->where('cars', 2)->get();
// 在查询结果中包括带被软删除的模型
// 在查询中使用 restore 方法,从而快速恢复多个模型。和其他批量」操作一样,这个操作不会触发模型的任何事件
Model::withTrashed()->where('cars', 2)->restore();
// 永久删除
// 要真实删除数据时,使用 forceDelete 方法即可
Model::where('cars', 2)->forceDelete();
// onlyTrashed 方法 只获取已软删除的模型(检索软删除模型)
Model::onlyTrashed()->where('cars', 2)->get();
四、模型关联
// 一对一 - User::phone()
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
// 一对一 - Phone::user(), 定义相对的关联
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
// 一对多 - Post::comments()
return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
// 一对多 - Comment::post()
return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
// 多对多 - User::roles();
return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
// 多对多 - Role::users();
return $this->belongsToMany('App\User');
// 多对多 - Retrieving Intermediate Table Columns
$role->pivot->created_at;
// 多对多 - 中介表字段
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
// 多对多 - 自动维护 created_at 和 updated_at 时间戳
return $this->belongsToMany('App\Role')->withTimestamps();
// 远层一对多 - Country::posts(), 一个 Country 模型可能通过中介的 Users
// 模型关联到多个 Posts 模型(User::country_id)
return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
// 多态关联 - Photo::imageable()
return $this->morphTo();
// 多态关联 - Staff::photos()
return $this->morphMany('App\Photo', 'imageable');
// 多态关联 - Product::photos()
return $this->morphMany('App\Photo', 'imageable');
// 多态关联 - 在 AppServiceProvider 中注册你的「多态对照表」
Relation::morphMap([
'Post' => App\Post::class,
'Comment' => App\Comment::class,
]);
// 多态多对多关联 - 涉及数据库表: posts,videos,tags,taggables
// Post::tags()
return $this->morphToMany('App\Tag', 'taggable');
// Video::tags()
return $this->morphToMany('App\Tag', 'taggable');
// Tag::posts()
return $this->morphedByMany('App\Post', 'taggable');
// Tag::videos()
return $this->morphedByMany('App\Video', 'taggable');
// 查找关联
$user->posts()->where('active', 1)->get();
// 获取所有至少有一篇评论的文章...
$posts = App\Post::has('comments')->get();
// 获取所有至少有三篇评论的文章...
$posts = Post::has('comments', '>=', 3)->get();
// 获取所有至少有一篇评论被评分的文章...
$posts = Post::has('comments.votes')->get();
// 获取所有至少有一篇评论相似于 foo% 的文章
$posts = Post::whereHas('comments', function ($query) {
$query->where('content', 'like', 'foo%');
})->get();
// 预加载
$books = App\Book::with('author')->get();
$books = App\Book::with('author', 'publisher')->get();
$books = App\Book::with('author.contacts')->get();
// 延迟预加载
$books->load('author', 'publisher');
// 写入关联模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post->comments()->save($comment);
// Save 与多对多关联
$post->comments()->saveMany([
new App\Comment(['message' => 'A new comment.']),
new App\Comment(['message' => 'Another comment.']),
]);
$post->comments()->create(['message' => 'A new comment.']);
// 更新「从属」关联
$user->account()->associate($account);
$user->save();
$user->account()->dissociate();
$user->save();
// 附加多对多关系
$user->roles()->attach($roleId);
$user->roles()->attach($roleId, ['expires' => $expires]);
// 从用户上移除单一身份...
$user->roles()->detach($roleId);
// 从用户上移除所有身份...
$user->roles()->detach();
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);
// 任何不在给定数组中的 IDs 将会从中介表中被删除。
$user->roles()->sync([1, 2, 3]);
// 你也可以传递中介表上该 IDs 额外的值:
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
五、模型事件
Eloquent 模型可以在模型生命周期中的各个时间点触发相应的事件
注意点:
1、依次是 saving>creating>created>saved。
2、update 同理就不具体贴代码了, saving>updating>updated>saved。
3、而 delete 不涉及 save,因此依次只触发了 deleting 和deleted。 当 restore 软删除记录时触发了 restoring 和 restored 方法。
4、Eloquent模型可以触发事件,允许你在模型生命周期中的多个时间点调用如下这些方法:creating, created, updating, updated, saving, saved,deleting, deleted, restoring, restored。事件允许你在一个指定模型类每次保存或更新的时候执行代码。
5、一个新模型被首次保存的时候,creating和created事件会被触发。如果一个模型已经在数据库中存在并调用save方法,updating/updated事件会被触发,无论是创建还是更新,saving/saved事件都会被调用.
6、deleting和deleted很好理解,在删除模型时触发,deleting在删除操作前执行,deleted在删除完成后执行。
7、当创建模型时,依次执行saving、creating、created和saved,同理在更新模型时依次执行saving、updating、updated和saved。无论是使用批量赋值(create/update)还是直接调用save方法,都会触发对应事件(前提是注册了相应的模型事件)。
// 从数据库中获取已存在模型时会触发该事件
// 数据库中检索现有模型时会触发 retrieved 事件
Model::retrieved(function($model){});
// 当一个新模型被首次保存的时候,这两个事件会被触发
• creating - 对象已经 ready 但未写入数据库
• created - 对象已经写入数据库
Model::creating(function($model){});
Model::created(function($model){});
// 当一个模型已经在数据库中存在并调用 save 方法,这两个事件会被触发
• updating - 对象已经修改但未写入数据库
• updated - 修改已经写入数据库
Model::updating(function($model){});
Model::updated(function($model){});
// 无论是创建还是更新,这两个事件都会被触发
• saving - 对象创建或者已更新但未写入数据库
• saved - 对象创建或者更新已经写入数据库
Model::saving(function($model){});
Model::saved(function($model){});
// 当一个新模型被删除的时候,这两个事件会被触发
• deleting - 删除前
• deleted - 删除后
Model::deleting(function($model){});
Model::deleted(function($model){});
// 当一个新模型恢复删除的时候,这两个事件会被触发
• restoring - 恢复软删除前
• restored - 恢复软删除后
Model::restoring(function($model){});
Model::restored(function($model){});
// 在某个服务提供者的 boot 方法中注册观察者
Model::observe(new FooObserver);
六、Eloquent 配置信息
// 关闭模型插入或更新操作引发的 「mass assignment」异常
Eloquent::unguard();
// 重新开启「mass assignment」异常抛出功能
Eloquent::reguard();
希望上面的总结能对大家有帮助,如果有问题,欢迎大家留言。