Eloquent ORM #
一、Eloquent概述 #
1.1 什么是Eloquent #
Eloquent是Laravel内置的ORM(对象关系映射),使用ActiveRecord模式,让数据库操作变得优雅简单。
php
// 每个Eloquent模型对应一张数据表
class User extends Model
{
//
}
// 使用模型操作数据库
$users = User::all();
$user = User::find(1);
$user->name = 'John';
$user->save();
1.2 创建模型 #
bash
php artisan make:model User
# 同时创建迁移文件
php artisan make:model User --migration
# 或
php artisan make:model User -m
1.3 模型约定 #
php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// 指定表名(默认使用类名的复数形式)
protected $table = 'my_users';
// 指定主键(默认为id)
protected $primaryKey = 'user_id';
// 禁用自增
public $incrementing = false;
// 主键类型
protected $keyType = 'string';
// 禁用时间戳
public $timestamps = false;
// 时间戳格式
protected $dateFormat = 'U';
// 默认属性值
protected $attributes = [
'active' => 1,
];
}
二、查询数据 #
2.1 获取所有数据 #
php
$users = User::all();
2.2 根据主键查询 #
php
// 查找单个
$user = User::find(1);
// 查找或抛出异常
$user = User::findOrFail(1);
$user = User::where('email', 'john@example.com')->firstOrFail();
// 查找多个
$users = User::find([1, 2, 3]);
2.3 条件查询 #
php
$users = User::where('active', 1)->get();
$user = User::where('email', 'john@example.com')->first();
// 链式调用
$users = User::where('active', 1)
->orderBy('name')
->take(10)
->get();
2.4 获取集合 #
php
$users = User::where('active', 1)->get();
// 遍历
foreach ($users as $user) {
echo $user->name;
}
2.5 分块处理 #
php
User::chunk(200, function ($users) {
foreach ($users as $user) {
// 处理用户
}
});
2.6 游标遍历 #
php
foreach (User::cursor() as $user) {
// 处理用户
}
三、插入数据 #
3.1 创建模型 #
php
// 方式一
$user = new User;
$user->name = 'John';
$user->email = 'john@example.com';
$user->save();
// 方式二
$user = User::create([
'name' => 'John',
'email' => 'john@example.com',
]);
3.2 批量赋值 #
php
class User extends Model
{
// 可批量赋值的字段
protected $fillable = ['name', 'email', 'password'];
// 不可批量赋值的字段
protected $guarded = ['id', 'is_admin'];
}
// 使用create方法
$user = User::create($request->all());
// 使用firstOrCreate
$user = User::firstOrCreate(['email' => 'john@example.com']);
// 使用firstOrNew(不保存)
$user = User::firstOrNew(['email' => 'john@example.com']);
// 使用updateOrCreate
$user = User::updateOrCreate(
['email' => 'john@example.com'],
['name' => 'John Doe']
);
四、更新数据 #
4.1 更新模型 #
php
$user = User::find(1);
$user->name = 'Jane';
$user->save();
4.2 批量更新 #
php
User::where('active', 0)
->update(['active' => 1]);
4.3 更新时间戳 #
php
$user->touch();
五、删除数据 #
5.1 删除模型 #
php
$user = User::find(1);
$user->delete();
5.2 根据主键删除 #
php
User::destroy(1);
User::destroy([1, 2, 3]);
5.3 条件删除 #
php
User::where('active', 0)->delete();
5.4 软删除 #
php
class User extends Model
{
use SoftDeletes;
}
// 迁移文件
Schema::table('users', function (Blueprint $table) {
$table->softDeletes();
});
// 使用
$user->delete(); // 软删除
$user->forceDelete(); // 强制删除
$user->restore(); // 恢复
// 查询
$users = User::withTrashed()->get(); // 包含软删除
$users = User::onlyTrashed()->get(); // 只查软删除
六、模型关联 #
6.1 一对一 #
php
class User extends Model
{
public function phone()
{
return $this->hasOne(Phone::class);
}
}
class Phone extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// 使用
$phone = $user->phone;
$user = $phone->user;
6.2 一对多 #
php
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
// 使用
$posts = $user->posts;
$user = $post->user;
6.3 多对多 #
php
class User extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
// 使用
$roles = $user->roles;
// 附加
$user->roles()->attach($roleId);
// 分离
$user->roles()->detach($roleId);
// 同步
$user->roles()->sync([1, 2, 3]);
// 切换
$user->roles()->toggle([1, 2, 3]);
6.4 远程一对多 #
php
class Country extends Model
{
public function posts()
{
return $this->hasManyThrough(Post::class, User::class);
}
}
6.5 多态关联 #
php
class Post extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
class Video extends Model
{
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
}
class Comment extends Model
{
public function commentable()
{
return $this->morphTo();
}
}
// 使用
$comments = $post->comments;
$commentable = $comment->commentable;
七、预加载 #
7.1 N+1问题 #
php
// 不推荐:N+1问题
$posts = Post::all();
foreach ($posts as $post) {
echo $post->user->name; // 每次循环都查询一次
}
// 推荐:预加载
$posts = Post::with('user')->get();
foreach ($posts as $post) {
echo $post->user->name; // 不再额外查询
}
7.2 预加载多个关联 #
php
$posts = Post::with(['user', 'comments'])->get();
7.3 嵌套预加载 #
php
$posts = Post::with('comments.user')->get();
7.4 条件预加载 #
php
$posts = Post::with(['comments' => function ($query) {
$query->where('approved', 1);
}])->get();
7.5 延迟预加载 #
php
$posts = Post::all();
// 之后预加载
$posts->load('user', 'comments');
八、访问器和修改器 #
8.1 访问器 #
php
class User extends Model
{
public function getNameAttribute($value)
{
return ucfirst($value);
}
// 定义虚拟属性
public function getFullNameAttribute()
{
return $this->first_name . ' ' . $this->last_name;
}
}
// 使用
echo $user->name; // 自动调用访问器
echo $user->full_name; // 虚拟属性
8.2 修改器 #
php
class User extends Model
{
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
}
// 使用
$user->password = 'secret'; // 自动加密
8.3 属性转换 #
php
class User extends Model
{
protected $casts = [
'options' => 'array',
'active' => 'boolean',
'created_at' => 'datetime',
'deleted_at' => 'immutable_datetime',
'price' => 'decimal:2',
];
}
// 使用
$user->options = ['key' => 'value']; // 自动转JSON
$options = $user->options; // 自动转数组
九、查询作用域 #
9.1 本地作用域 #
php
class User extends Model
{
public function scopeActive($query)
{
return $query->where('active', 1);
}
public function scopeOfType($query, $type)
{
return $query->where('type', $type);
}
}
// 使用
$users = User::active()->get();
$users = User::ofType('admin')->get();
9.2 全局作用域 #
php
class SoftDeletingScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->whereNull($model->getQualifiedDeletedAtColumn());
}
}
// 注册
protected static function booted()
{
static::addGlobalScope(new SoftDeletingScope);
}
// 移除
User::withoutGlobalScope(SoftDeletingScope::class)->get();
十、模型事件 #
10.1 事件类型 #
| 事件 | 说明 |
|---|---|
| retrieved | 从数据库获取后 |
| creating | 创建前 |
| created | 创建后 |
| updating | 更新前 |
| updated | 更新后 |
| saving | 保存前 |
| saved | 保存后 |
| deleting | 删除前 |
| deleted | 删除后 |
| restoring | 恢复前 |
| restored | 恢复后 |
10.2 定义事件监听 #
php
class User extends Model
{
protected static function booted()
{
static::created(function ($user) {
// 用户创建后执行
});
static::updating(function ($user) {
// 用户更新前执行
});
}
}
10.3 使用Observer #
bash
php artisan make:observer UserObserver --model=User
php
// app/Observers/UserObserver.php
class UserObserver
{
public function created(User $user)
{
//
}
public function updated(User $user)
{
//
}
}
// 注册
// app/Providers/AppServiceProvider.php
public function boot()
{
User::observe(UserObserver::class);
}
十一、总结 #
11.1 核心概念 #
| 概念 | 说明 |
|---|---|
| 模型 | 对应数据表 |
| 关联 | 表之间的关系 |
| 访问器 | 获取属性时转换 |
| 修改器 | 设置属性时转换 |
| 作用域 | 可复用的查询条件 |
| 事件 | 模型生命周期事件 |
11.2 下一步 #
掌握了Eloquent ORM后,让我们继续学习 数据库迁移,了解如何管理数据库结构!
最后更新:2026-03-28