Eloquent ORM模型
通常完成实际的业务逻辑和数据封装,并返回和格式无关的数据
生成模型类
创建一个 Eloquent
模型。模型通常位于 app\Models
目录中,并扩展 Illuminate\Database\Eloquent\Model
类
# 生成模型
php artisan make:model Flight
# 生成模型和 migration 数据库迁移
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
# 生成模型和迁移(m)、工厂(f)、数据填充(s)、控制器(c)...
php artisan make:model Flight -mfsc
模型属性
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
// 设置当前模型对应的完整数据表名称
protected $table = 'my_flights';
// 如果该数据表的主键不是id,那么需要设置主键属性
protected $primaryKey = 'flight_id';
// 如果主键不是自增或者不是数字类型
public $incrementing = false;
// 如果模型主键不是 integer
protected $keyType = 'string';
}
时间戳
默认情况下,Eloquent
希望模型相应的数据库表中存在 created_at
和 updated_at
这两个字段,在新增数据或者更新数据时 Eloquent
会自动设置这两个字段的值,如果不需要自动写入,需要在模型定义 $timestamps
属性并且值为false
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
// 是否主动维护时间戳
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';
// 如果不需要定义UPDATED_AT常量,该属性的值设置为null
const UPDATED_AT = 'updated_date';
}
ORM 查询数据
在模型中除了可以调用数据库类的方法之外(换句话说,数据库的所有查询构造器方法模型中都可以支持),可以定义自己的方法,所以也可以把模型看成是数据库的增强版
// 引入模型
use App\Models\Flight;
// 根据[$id]主键查询 查询一条数据
$flight = Flight::find(1);
//first() 查询第一条
$flight = Flight::where('id','>','1')->orderBy('age','desc')->first();
// findOrFail() 根据主键查询 如果没有查到 报错
$flight = Flight::findOrFail($id);
// all() 查询所有数据 查询数据为集合
$flight = Flight::all();
// chunk() 每次查询指定[$num]条数 当处理大量模型数据的时候,使用该方法会明显减少内存的使用量
Flight::chunk($num,function($data){
print_r($data);
} );
// 聚合函数 count() 统计记录条数
$num = Flight::count();
// 聚合函数 max() 查询最大值 min() 查询最小值
$max = Flight::where('id','>',1)->max('age');
ORM 插入数据
要往数据库新增一条记录,先创建新模型实例,给实例设置属性,然后调用 save 方法
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Flight;
use Illuminate\Http\Request;
class FlightController extends Controller
{
/**
* 创建一个新实例
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
}
批量赋值
你也可以使用 create
方法来保存新模型。 此方法会返回模型实例。 不过,在使用之前,你需要在模型上指定 fillable
或 guarded
属性,因为所有的 Eloquent 模型都默认不可进行批量赋值
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 可批量赋值属性
*
* @var array
*/
protected $fillable = ['name'];
}
如果想让所有属性都可以批量赋值,可以将 $guarded 定义成一个空数组
/**
* 不可批量赋值的属性
*
* @var array
*/
protected $guarded = [];
这样就可以使用create静态方法实现批量赋值
use App\Models\Flight;
$flight = Flight::create([
'xm' => '小白',
'sex' => '男',
'age' => '18',
]);
ORM 更新数据
save
方法也可以用来更新数据库中已经存在的模型。 要更新模型,您应该检索它并设置您希望更新的任何属性。 然后调用模型的 save
方法。 同样,updated_at
时间戳会自动更新,因此无需手动设置其值
use App\Models\Flight;
$flight = Flight::find(1);
$flight->name = 'Paris to London';
$flight->save();
批量更新
也可以更新匹配查询条件的多个模型。在这个示例中,所有的男生所在系部变为1
use App\Models\Flight;
$flight = Flight::where('sex', 1)
->update(['depid' => 1]);
updateOrCreate
你还可能遇到希望更新现有模型或在不存在的情况下则创建新的模型的情景。 Laravel 提供 updateOrCreate
方法来一步实现。将id为20的同学信息改为性别男,所在系部为3
use App\Models\Flight;
$flight = Flight::updateOrCreate(
['xh'=>9512101],
['sex' => 1, 'depid' => 3]
);
ORM 删除
可以在模型实例上调用 delete
方法来删除实例
use App\Models\Flight;
$flight = Flight::find(1);
$flight->delete();
通过主键删除模型
在上面的例子中,在调用 delete
之前需要先去数据库中查找对应的模型。事实上,如果你知道了模型的主键,你可以直接使用 destroy
方法来删除模型,而不用先去数据库中查找。destroy
方法除了接受单个主键作为参数之外,还接受多个主键,或者使用数组、集合来保存多个主键
use App\Models\Flight;
// 删除单条
$flight = Flight::destroy(1);
// 删除多个主键
$flight = Flight::destroy(1, 2, 3);
// 一个主键数组或一个主键集合
$flight = Flight::destroy([1, 2, 3]);
使用查询删除模型
通过 Eloquent 查询来删除所有符合查询条件的模型。 例如,将删除所有标记为非活跃的航班。与批量更新一样,批量删除不会为删除的模型启动任何模型事件
$deletedRows = Flight::where('active', 0)->delete();
软删除
除了真实删除记录,还可以 "软删除"。 软删除不会从数据库中删除,而是在 deleted_at 属性中设置删除模型的日期和时间。要启用软删除,请在模型中添加 Illuminate\Database\Eloquent\SoftDeletes
trait
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
use SoftDeletes;
}
还需要把 deleted_at
字段添加到数据表中,注意: deleted_at 字段名无法重新设置,且数据格式必须为datetime,直接调用 delete()
方法或者 destroy()
方法即可
use App\Models\Flight;
$flight = Flight::destroy($id);
恢复删除
use App\Models\Flight;
$flight = Flight::onlyTrashed()->where('id', $id)->restore();
永久删除
有时可能需要从数据库中真正删除数据。要从数据库中永久删除软删除的数据,请使用 forceDelete
方法
use App\Models\Flight;
$flight = Flight::forceDeleted($id);
查询软删除数据
查询包含软删除的数据
可以使用 withTrashed
方法来获取包括软删除模型在内的数据
use App\Models\Flight;
$flights = Flight::withTrashed()
->where('account_id', 1)
->get();
只查询软删除的数据
`onlyTrashed` 方法 只获取已软删除的数据
$flights = Flight::onlyTrashed()
->where('airline_id', 1)
->get();
属性访问器
若要定义一个访问器, 则需在模型上创建一个 getDingAttribute
方法,要访问的 Ding
字段需使用「驼峰式」命名。 在这个示例中,我们将为 ding
属性定义一个访问器。当模型尝试获取 ding
属性时,将自动调用此访问器
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 获取用户名
*
* @param string $value
* @return string
*/
public function getFirstNameAttribute($value)
{
return strtolower($value); // 转小写
}
}
字段的原始值被传递到访问器中,允许对它进行处理并返回结果。如果想获取被修改后的值,你可以在模型实例上访问 first_name
属性
use App\Models\User;
$user = User::find(1);
$firstName = $user->first_name; // 得到小写的名字
属性修改器
若要定义一个修改器,则需在模型上面定义 setFooAttribute
方法。要访问的 Foo 字段使用「驼峰式」命名。让我们再来定义一个 first_name
属性的修改器。当我们尝试使用 first_name
属性值时,该修改器将被自动调用
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 设置用户名
*
* @param string $value
* @return void
*/
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}
修改器会获取属性已经被设置的值,允许你修改并且将其值设置到 Eloquent 模型内部的 $attributes
属性上。举个例子,如果我们尝试将 first_name
属性的值设置为 DING
use App\Models\User;
$user = User::find(1);
$user->first_name = 'Sally';