Eloquent: 入门
简介
Laravel 的 Eloquent ORM 提供了漂亮、简洁的 ActiveRecord 实现来和数据库进行交互。每个数据库表都有一个对应的「模型」可用来跟数据表进行交互。你可以通过模型查询数据表内的数据,以及将记录添加到数据表中。
在开始之前,请确认你已在 config/database.php
文件中设置好了数据库连接。更多数据库的设置信息请查看 数据库设置 文档。
定义模型
开始之前,让我们先来创建一个 Eloquent 模型。模型通常放在 app
目录中,不过你可以将他们随意放在任何可通过 composer.json
自动加载的地方。所有的 Eloquent 模型都继承自 Illuminate\Database\Eloquent\Model
类。
创建模型实例的最简单方法是使用 make:model
Artisan 命令:
php artisan make:model User
当你生成一个模型时想要顺便生成一个 数据库迁移,可以使用 --migration
或 -m
选项:
php artisan make:model User --migration
php artisan make:model User -m
Eloquent 模型约定
现在,让我们来看一个 Flight
模型类的例子,我们将会用它从 flights
数据表中取回与保存信息:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
//
}
数据表名称
请注意,我们并没有告诉 Eloquent Flight
模型该使用哪一个数据表。除非数据表明确地指定了其它名称,否则将使用类的「蛇形名称」、复数形式名称来作为数据表的名称。因此在此例子中,Eloquent 将会假设 Flight
模型被存储记录在 flights
数据表中。你可以在模型上定义一个 table
属性,用来指定自定义的数据表名称:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 与模型关联的数据表
*
* @var string
*/
protected $table = 'my_flights';
}
主键
Eloquent 也会假设每个数据表都有一个叫做 id
的主键字段。你也可以定义一个 $primaryKey
属性来重写这个约定。
此外,Eloquent 假定主键是一个递增的整数值,这意味着在默认情况下主键将自动的被强制转换为 int
。 如果你想使用非递增或者非数字的主键,你必须在你的模型 public $incrementing
属性设置为false
。
时间戳
默认情况下,Eloquent 会认为在你的数据库表有 created_at
和 updated_at
字段。如果你不希望让 Eloquent 来自动维护这两个字段,可在模型内将 $timestamps
属性设置为 false
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 该模型是否被自动维护时间戳
*
* @var bool
*/
public $timestamps = false;
}
如果你需要自定义自己的时间戳格式,可在模型内设置 $dateFormat
属性。这个属性决定了日期应如何在数据库中存储,以及当模型被序列化成数组或 JSON 格式:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 模型的日期字段保存格式。
*
* @var string
*/
protected $dateFormat = 'U';
}
数据库连接
默认情况下,所有的 Eloquent 模型会使用应用程序中默认的数据库连接设置。如果你想为模型指定不同的连接,可以使用 $connection
属性:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 此模型的连接名称。
*
* @var string
*/
protected $connection = 'connection-name';
}
取回多个模型
一旦你创建并 关联了一个模型到数据表 上,那么你就可以从数据库中获取数据。可把每个 Eloquent 模型想像成强大的 查询构造器,它让你可以流畅地查询与模型关联的数据表。例如:
<?php
use App\Flight;
$flights = App\Flight::all();
foreach ($flights as $flight) {
echo $flight->name;
}
增加额外的限制
Eloquent 的 all
方法会返回在模型数据表中的所有结果。由于每个 Eloquent 模型都可以当作一个 查询构造器,所以你可以在查询中增加规则,然后使用 get
方法来获取结果:
$flights = App\Flight::where('active', 1)
->orderBy('name', 'desc')
->take(10)
->get();
由于 Eloquent 模型是查询构造器,因此你应当去阅读所有 查询构造器 中可用的方法。你可在 Eloquent 查询中使用这其中的任何方法。
集合
类似 all
以及 get
之类的可以取回多个结果的 Eloquent 方法,将会返回一个 Illuminate\Database\Eloquent\Collection
实例。Collection
类提供 多种辅助函数 来处理你的 Eloquent 结果。
$flights = $flights->reject(function ($flight) {
return $flight->cancelled;
});
当然,你也可以简单地像数组一样来遍历集合:
foreach ($flights as $flight) {
echo $flight->name;
}
分块结果
如果你需要处理数以千计的 Eloquent 查找结果,则可以使用 chunk
命令。chunk
方法将会获取一个 Eloquent 模型的「分块」,并将它们送到指定的 闭包 (Closure)
中进行处理。当你在处理大量结果时,使用 chunk
方法可节省内存:
Flight::chunk(200, function ($flights) {
foreach ($flights as $flight) {
//
}
});
传递到方法的第一个参数表示每次「分块」时你希望接收的数据数量。闭包则作为第二个参数传递,它将会在每次从数据取出分块时被调用。
使用游标
cursor
允许你使用游标来遍历数据库数据,一次只执行单个查询。在处理大数据量请求时 cursor
方法可以大幅度减少内存的使用:
foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
//
}