Laravel Eloquent ORM高级用法
Eloquent是Laravel框架的核心ORM,它以优雅的Active Record模式让数据库操作变得简单直观。但很多开发者只停留在基本的CRUD操作,没有发挥出Eloquent的全部威力。本文将介绍Eloquent的高级用法和最佳实践。
一、关联关系进阶
// 多态关联 - 一个模型可属于多种父模型
class Comment extends Model
{
public function commentable()
{
return this->morphTo();
}
}
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 Tag extends Model
{
public function posts()
{
return this->morphedByMany(Post::class, "taggable");
}
public function videos()
{
return this->morphedByMany(Video::class, "taggable");
}
}
二、查询优化
// N+1问题解决方案
// 问题:循环中查询关联
var users = User::all();
users.forEach(function(user) {
console.log(user.posts); // 每次都查询一次!
});
// 解决1:预加载
var users = User::with("posts")->get();
// 解决2:延迟预加载
var users = User::all();
users.load("posts");
// 解决3:关联预加载带条件
var users = User::with(["posts" => function(query) {
query->where("published", true)->latest()->limit(5);
}])->get();
// 解决4:使用join代替子查询
User::select("users.*", "posts.title")
->join("posts", "users.id", "=", "posts.user_id")
->get();
三、Accessor与Mutator
// Accessor - 获取时转换
class User extends Model
{
public function getFullNameAttribute()
{
return this->first_name + " " + this->last_name;
}
// Laravel 9+ 新写法
protected function fullName(): Attribute
{
return Attribute::make(
get: fn () => this->first_name + " " + this->last_name,
);
}
}
// Mutator - 设置时转换
protected function password(): Attribute
{
return Attribute::make(
set: fn (value) => bcrypt(value),
);
}
// 同时定义获取和设置
protected function name(): Attribute
{
return Attribute::make(
get: fn (value) => ucfirst(value),
set: fn (value) => strtolower(value),
);
}
四、模型事件与观察者
// 观察者
class UserObserver
{
public function creating(User user)
{
// 创建前
}
public function created(User user)
{
// 创建后 - 发送欢迎邮件
Mail::to(user)->send(new WelcomeEmail());
}
public function deleting(User user)
{
// 删除前 - 清理关联数据
user->posts()->delete();
}
}
// 注册观察者
User::observe(UserObserver::class);
Eloquent的强大在于它的优雅和表达力。掌握高级用法可以让数据库操作更加简洁高效,同时保持代码的可读性和可维护性。建议多阅读Laravel源码,理解Eloquent的内部实现机制。