Eloquent: 快速入门
简介
Laravel包含的Eloquent模块,是一个对象关系映射(ORM),能使你更愉快地交互数据库。当你使用Eloquent时,数据库中每张表都有一个相对应的"模型"用于操作这张表。除了能从数据表中检索数据记录之外,Eloquent模型同时也允许你新增,更新和删除这对应表中的数据
开始使用之前, 请确认在你的项目里的config/database.php
配置文件中已经配置好一个可用的数据库连接. 关于配置数据库的更多信息, 请查阅数据库配置文档.
Laravel 训练营
如果你是 Laravel 的新手,可以随时前往 Laravel 训练营。Laravel 训练营将指导你使用 Eloquent 建立你的第一个 Laravel 应用。这是一个很好的方式来了解 Laravel 和 Eloquent 所提供的一切。
生成模型类
首先,让我们创建一个 Eloquent 模型。模型通常位于 app\Models
目录中,并继承 Illuminate\Database\Eloquent\Model
类。 你可以使用 make:model
Artisan 命令 来生成新模型类:
php artisan make:model Flight
如果你想要在生成模型类的同时生成 数据库迁移, 可以使用 --migration
或 -m
选项:
php artisan make:model Flight --migration
在生成模型的同时,你可能还想要各种其他类型的类,例如模型工厂、数据填充和控制器。这些选项可以组合在一起从而一次创建多个类:
# 生成模型和 Flight 工厂类...
php artisan make:model Flight --factory
php artisan make:model Flight -f
# 生成模型和 Flight 数据填充类...
php artisan make:model Flight --seed
php artisan make:model Flight -s
# 生成模型和 Flight 控制器类...
php artisan make:model Flight --controller
php artisan make:model Flight -c
# 生成模型,Flight 控制器类,资源类和表单验证类...
php artisan make:model Flight --controller --resource --requests
php artisan make:model Flight -crR
# 生成模型和 Flight 授权策略类...
php artisan make:model Flight --policy
# 生成模型和数据库迁移,Filght 工厂类,数据库填充类和 Flight 控制器...
php artisan make:model Flight -mfsc
# 快捷生成模型,数据库迁移,Flight 工厂类,数据库填充类,授权策略类,Flight 控制器和表单验证类...
php artisan make:model Flight --all
# 生成中间表模型...
php artisan make:model Member --pivot
检查模型
有时,仅仅通过略读代码来确定一个模型的所有可用属性和关系是很困难的。作为替代,试试 model:show
Artisan 命令,它提供了一个对于模型的所有属性和关系的方便概述。
php artisan model:show Flight
Eloquent 模型约定
由 make:model
命令生成的模型会被放置在 app/Models
目录下。让我们检查一个基本的模型类并讨论 Eloquent 的一些关键约定:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
// ...
}
数据表名称
看了上面的例子,你可能已经注意到我们没有告诉 Eloquent 哪个数据库表对应我们的 Flight
模型。按照约定,除非明确指定另一个名称,类名称的下划线格式的复数形态将被用作表名。因此,在这个例子中,Eloquent 将假定 Flight
模型将记录存储在 flights
表中,而 AirTrafficController
模型将记录存储在 air_traffic_controllers
表中。
如果你的模型对应的数据表不符合这个约定,你可以通过在模型上定义一个 table
属性来手动指定模型的表名:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 与模型关联的数据表。
*
* @var string
*/
protected $table = 'my_flights';
}
主键
Eloquent 还会假设每个模型对应的数据表都有一个名为 id
的列作为主键。如有必要,你可以在模型上定义一个受保护的 $primaryKey
属性,来指定一个不同的列名称用作模型的主键:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 与数据表关联的主键。
*
* @var string
*/
protected $primaryKey = 'flight_id';
}
此外,Eloquent 默认有一个 integer 值的主键,Eloquent 会自动转换这个主键为一个 integer 类型,如果你的主键不是自增或者不是数字类型,你可以在你的模型上定义一个 public 属性的 $incrementing
,并将其设置为 false
:
<?php
class Flight extends Model
{
/**
* 指明模型的ID是否自动递增。
*
* @var bool
*/
public $incrementing = false;
}
如果你的模型主键不是 integer
,应该定义一个 protected $keyType
属性在模型上,其值应为 string
:
<?php
class Flight extends Model
{
/**
* 自动递增ID的数据类型。
*
* @var string
*/
protected $keyType = 'string';
}
复合主键
Eloquent 要求每个模型至少有一个可以作为其主键的唯一标识 ID。它不支持「复合」主键。但是,除了表的唯一标识主键之外,还可以向数据库表添加额外的多列唯一索引。
UUID 与 ULID 键
你可以选择使用UUID,而不是使用自动递增的整数作为Elquent模型的主键。UUID是36个字符长的通用唯一字母数字标识符。
如果你希望模型使用UUID键而不是自动递增的整数键,可以在模型上使用 Illuminate\Database\Eloquent\Concerns\HasUuids
trait,在此情况下应该确保模型具有 UUID相等的主键列:
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasUuids;
// ...
}
$article = Article::create(['title' => 'Traveling to Europe']);
$article->id; // "8f8e8478-9035-4d23-b9a7-62f4d2612ce5"
默认情况下,HasUuids
trait 将会为模型生成 「ordered」 UUIDs 。 这些 UUIDs 对于索引数据库存储更有效,因为它们可以按字典顺序进行排序。
通过在模型中定义一个 newUniqueId
方法,你可以推翻给定模型的 UUID 生成方法。此外,你可以通过模型中的 uniqueIds
方法,来指定哪个字段是需要接收 UUIDs:
use Ramsey\Uuid\Uuid;
/**
* 为模型生成一个新的 UUID。
*/
public function newUniqueId(): string
{
return (string) Uuid::uuid4();
}
/**
* 获取应该接收唯一标识符的列。
*
* @return array<int, string>
*/
public function uniqueIds(): array
{
return ['id', 'discount_code'];
}
如果你愿意,你可以选择利用 「ULIDs」 来替代 UUIDs。 ULIDs 类似于 UUIDs; 然而,它们的长度仅为 26 字符。类似于订单 UUIDs, ULIDs 是字典顺序排序,以实现高效的数据索引。为了利用 ULIDs, 你需要在你的模型中引用 Illuminate\Database\Eloquent\Concerns\HasUlids
trait。 同样还需要确保模型中有一个 ULID 匹配的主键字段:
use Illuminate\Database\Eloquent\Concerns\HasUlids;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
use HasUlids;
// ...
}
$article = Article::create(['title' => 'Traveling to Asia']);
$article->id; // "01gd4d3tgrrfqeda94gdbtdk5c"
时间戳
默认情况下,Eloquent 需要 created_at
和 updated_at
字段存在你的模型数据表中。当模型被创建或更新时,Eloquent 将自动地设置这些字段的值。如果你不想让这些字段被 Eloquent 自动管理,你需要在你的模型中定义一个 $timestamps
属性并赋值为 false
:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 指示模型是否主动维护时间戳。
*
* @var bool
*/
public $timestamps = false;
}
如果你需要自定义模型时间戳的格式,请在模型上设置 $dateFormat
属性。以此来定义时间戳在数据库中的存储方式以及模型序列化为数组或 JSON 时的格式:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 模型日期字段的存储格式。
*
* @var string
*/
protected $dateFormat = 'U';
}
如果需要自定义用于存储时间戳的字段的名称,可以在模型上定义 CREATED_AT
和 UPDATED_AT
常量:
<?php
class Flight extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'updated_date';
}