Eloquent: 入门
简介
Laravel 包含了 Eloquent,这是一个对象关系映射器(ORM),使与数据库的交互变得很愉快。使用 Eloquent 时,每个数据库表都有一个对应的「模型」,用于与该表进行交互。除了从数据库表中检索记录外,Eloquent 模型还允许您从表中插入,更新和删除记录。
技巧:在开始之前,请确保在应用的 config/database.php
配置文件中配置数据库连接。有关配置数据库的更多信息,请参阅 数据库配置文档。
生成模型类
首先,让我们创建一个 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
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
。它不支持「复合」主键。但是,除了表的唯一标识主键之外,还可以向数据库表添加额外的多列唯一索引。
时间戳
默认情况下,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';
}
数据库连接
默认情况下,所有 Eloquent 模型使用的是应用程序配置的默认数据库连接。如果想指定在与特定模型交互时应该使用的不同连接,可以在模型上定义$connection
属性:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 设置当前模型使用的数据库连接名。
*
* @var string
*/
protected $connection = 'sqlite';
}
默认属性值
默认情况下,被实例化的模型不会包含任何属性值。如果想为模型的某些属性定义默认值,可以在模型上定义一个 $attributes
属性:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 模型的属性默认值。
*
* @var array
*/
protected $attributes = [
'delayed' => false,
];
}
检索模型
一旦你创建了一个模型和 其关联的数据库表,就可以开始从数据库中检索数据了。可以将每个 Eloquent 模型视为一个强大的 查询构建器,让你能流畅地查询与该模型关联的数据库表。模型中的 all
方法将从模型的关联数据库表中检索所有记录:
use App\Models\Flight;
foreach (Flight::all() as $flight) {
echo $flight->name;
}