什么是 Eloquent ORM
Laravel 内置了名为 Eloquent 的对象关系映射器(ORM)。
Eloquent 采用 ActiveRecord 模式,用于简化数据库交互。
使用 Eloquent 时,为每张数据库表准备一个对应的「模型」类。
通过模型可以完成记录的查询、插入、更新与删除。
使用 Eloquent 之前,请先在 config/database.php 中配置数据库连接。
默认使用 .env 中的 DB_* 设置。
创建模型
使用 make:model Artisan 命令生成新模型:
php artisan make:model Post
同时创建迁移:
php artisan make:model Post -m
模型会生成到 app/Models:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
// ...
}
模型与表的对应
Eloquent 会根据类名推断表名:将类名转换为下划线复数形式。
| 模型名 | 表名 |
|---|
Post | posts |
User | users |
AirTrafficController | air_traffic_controllers |
不符合命名约定时,可在模型中定义 $table 属性:
class Post extends Model
{
protected $table = 'blog_posts';
}
时间戳
Eloquent 默认自动维护 created_at 和 updated_at。
在迁移中调用 $table->timestamps() 即可,保存或更新时会自动写入。
关闭自动维护:
class Post extends Model
{
public $timestamps = false;
}
批量赋值保护
批量保存数据时需要配置批量赋值保护。
fillable
用 $fillable 指定允许批量赋值的列:
class Post extends Model
{
protected $fillable = [
'user_id',
'title',
'body',
'published',
];
}
guarded
反向指定禁止赋值的列使用 $guarded:
class Post extends Model
{
// 仅保护主键,允许其余全部
protected $guarded = ['id'];
}
将 $guarded 设为空数组会允许所有列被赋值。若直接接收用户输入,可能造成意外列被修改。建议使用 $fillable 明确许可范围。
Eloquent 查询执行流程
User::where()->get() 的内部流程如下:
基本 CRUD
use App\Models\Post;
$posts = Post::all();
带条件:
// 已发布的文章
$publishedPosts = Post::where('published', true)->get();
// 第一条
$post = Post::where('published', true)->first();
// 按 ID 查
$post = Post::find(1);
// 未找到时返回 404
$post = Post::findOrFail(1);
需要设置 $fillable:
$post = Post::create([
'title' => '第一篇文章',
'body' => 'Laravel 是很棒的框架。',
'published' => true,
]);
或逐个赋值:
$post = new Post;
$post->title = '第一篇文章';
$post->body = 'Laravel 是很棒的框架。';
$post->save();
$post = Post::find(1);
$post->title = '新标题';
$post->save();
或批量更新:
Post::find(1)->update([
'title' => '新标题',
'published' => true,
]);
批量更新符合条件的多条:
Post::where('published', false)->update(['published' => true]);
$post = Post::find(1);
$post->delete();
按 ID 直接删除:
Post::destroy(1);
// 批量删除
Post::destroy([1, 2, 3]);
基础查询方法
| 方法 | 说明 |
|---|
Post::all() | 取全部记录 |
Post::find($id) | 按 ID 取(未找到返回 null) |
Post::findOrFail($id) | 按 ID 取(未找到返回 404) |
Post::where('column', 'value')->get() | 取满足条件的记录 |
Post::where('column', 'value')->first() | 第一条 |
Post::where('column', 'value')->count() | 数量 |
Post::orderBy('created_at', 'desc')->get() | 按某列排序 |
Post::latest()->get() | 按 created_at 降序 |
Post::limit(10)->get() | 限制条数 |
实践示例:使用 Post 模型
一个基于迁移创建的 posts 表的控制器示例:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class PostController extends Controller
{
// 文章列表
public function index(): View
{
$posts = Post::where('published', true)
->latest()
->get();
return view('posts.index', ['posts' => $posts]);
}
// 创建
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
'published' => ['boolean'],
]);
Post::create([
...$validated,
'user_id' => $request->user()->id,
]);
return redirect('/posts');
}
// 更新
public function update(Request $request, Post $post): RedirectResponse
{
$validated = $request->validate([
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
]);
$post->update($validated);
return redirect('/posts');
}
// 删除
public function destroy(Post $post): RedirectResponse
{
$post->delete();
return redirect('/posts');
}
}
在控制器方法参数中写 Post $post,Laravel 会通过路由模型绑定自动取回模型,无需再写 Post::findOrFail($id)。
模型事件生命周期
调用 save() 时触发事件的顺序如下。新建与更新触发不同的事件,saving、saved 在两种情况下都会触发。
下一步
迁移
回顾如何通过迁移创建 Eloquent 所用的数据表。