简介
Laravel框架使用Eloquent ORM提供美观、简捷的ActiveRecord来实现与数据库的交互。每张数据表对应一个模型。
在开始之前,确保在app/config/database.php中配置了数据库连接信息。
基本使用
首先创建一个Eloquent模型,模型类通常在app/models目录下,当然你也可以将其放在别处,前提是composer.json文件能自动加载它。
定义一个Eloquent模型
class User extends Eloquent {}
注意我们并没有告诉Eloquent用哪张表关联User模型,Eloquent会将其自动关联到users表(小写的复数名),你也可以通过table属性自定义对应表名:
class User extends Eloquent { protected $table = 'my_users'; }
注意:Eloquent假设每张表有一个主键——id,你可以通过primaryKey属性覆盖之。类似的,你可以使用connection属性来覆盖数据库连接名。
一个模型创建好了之后,你就可以读取/存储记录到数据表。
获取所有记录:
$users = User::all();
通过主键获取一条记录
$user = User::find(1); var_dump($user->name);
注意:query builder中有效的方法在Eloquent模型中依然有效。
抛出异常
有时候没有查询到数据时我们想要抛出一个异常,这里我们可以使用App::error处理器并显示一个404页面:
$model = User::findOrFail(1); $model = User::where('votes', '>', 100)->firstOrFail();
监听ModelNotFoundException来注册错误处理器:
use Illuminate\Database\Eloquent\ModelNotFoundException; App::error(function(ModelNotFoundException $e) { return Response::make('Not Found', 404); });
使用Eloquent模型进行查询
$users = User::where('votes', '>', 100)->take(10)->get(); foreach ($users as $user) { var_dump($user->name); }
Eloquent聚合
$count = User::where('votes', '>', 100)->count();
或者
$users = User::whereRaw('age > ? and votes = 100', array(25))->get();
结果分块
如果你一次性处理大量数据,使用chunk命令避免一次消耗大量内存:
User::chunk(200, function($users) { foreach ($users as $user) { // } });
指定查询连接
在执行Eloquent查询的时候还可以指定数据库连接:
$user = User::on('connection-name')->find(1);
安全过滤(Mass Assignment)
当创建一个新模型时,属性以数组形式传递给模型构造函数,这些属性然后通过mass-assienment分配给模型,这很方便,但是如果盲目地传递用户输入给模型的时候会有安全问题——用户可以自由地修改模型的所有属性,基于这个原因,Eloquent模型在mass-assignment时进行了保护。
定义fillable属性
fillable指定那些模型属性可以直接进行赋值:
class User extends Eloquent { protected $fillable = array('first_name', 'last_name', 'email'); }
定义guarded属性
与fillable相反,guarded是“黑名单”:
class User extends Eloquent { protected $guarded = array('id', 'password'); }
注意:使用guarded时,不可以传输Input::get()或者任何其他用户原生输入到save或者update方法,因为guarded中定义的列不会被更新。
所有属性都进行安全过滤
protected $guarded = array('*');
Insert、Update、Delete
新增一个新模型
$user = new User; $user->name = 'John'; $user->save();
注意:通常,Eloquent模型有自增键,如果想要指定自己的键值,可以设置incrementing属性为false。
你还可以使用create方法新增模型,该方法会返回插入的模型实例,当然在此之前,需要指定模型的fillable或者guarded属性,以保护mass-assignment。
在使用自增ID保存或创建新模型之后,可以通过对象的id属性获取自增ID:
$insertedId = $user->id;
设置guarded属性
class User extends Eloquent { protected $guarded = array('id', 'account_id'); }
使用模型的create方法
// Create a new user in the database... $user = User::create(array('name' => 'John')); // Retrieve the user by the attributes, or create it if it doesn't exist... $user = User::firstOrCreate(array('name' => 'John')); // Retrieve the user by the attributes, or instantiate a new instance... $user = User::firstOrNew(array('name' => 'John'));
更新模型
$user = User::find(1); $user->email = 'john@foo.com'; $user->save();
保存模型及关联
有时候想要保存的并不仅仅是模型本身,还包括其关联模型,可以通过push方法来实现:
$user->push();
还可以通过查询更新一系列模型:
$affectedRows = User::where('votes', '>', 100)->update(array('status' => 2));
注意:如果通过Eloquent query builder进行更新则模型事件不会被触发。
删除一个已存在的模型
$user = User::find(1); $user->delete();
通过Key删除已存在的模型
User::destroy(1); User::destroy(array(1, 2, 3)); User::destroy(1, 2, 3);
当然你也可以通过查询删除一系列模型:
$affectedRows = User::where('votes', '>', 100)->delete();
只更新模型的时间戳
$user->touch();
软删除
对一个模型进行软删除操作并不会真正在数据库中删除这条记录而是在该记录上设置一个delete_at时间戳,启用模型的软删除,可以通过SoftDeletingTrait来实现:
use Illuminate\Database\Eloquent\SoftDeletingTrait; class User extends Eloquent { use SoftDeletingTrait; protected $dates = ['deleted_at']; }
可以通过softDeletes方法添加deleted_at列到数据表:
$table->softDeletes();
现在,调用模型的delete方法,deleted_at列将会被设置为当前时间戳,这样在后续查询中,被“删除”的记录将不会出现。
强制软删除记录到模型查询结果
$users = User::withTrashed()->where('account_id', 1)->get();
withTrashed方法还可用于关联查询:
$user->posts()->withTrashed()->get();
如果你只想获取软删除的结果,可以使用onlyTrashed方法:
$users = User::onlyTrashed()->where('account_id', 1)->get();
如果想要恢复软删除结果到激活状态,使用restore方法:
$user->restore();
查询中使用restore:
User::withTrashed()->where('account_id', 1)->restore();
和withTrashed一样,restore方法还可以用于关联:
$user->posts()->restore();
如果你想要从数据库中完全移除模型,可以使用forceDelete方法:
$user->forceDelete();
forceDelete方法也可用于关联结果:
$user->posts()->forceDelete();
判读给定模型是否被软删除,可以通过trashed方法:
if ($user->trashed()) { // }
时间戳
默认情况下,Eloquent会在数据库中自动包含created_at和deleted_at两个列,你只管将这些时间戳列添加到数据表,剩下的Eloquent帮你打理,如果你想要数据库包含这些时间戳列,添加如下属性到模型中:
关闭自动时间戳
class User extends Eloquent { protected $table = 'users'; public $timestamps = false; }
提供自定义时间戳格式
class User extends Eloquent { protected function getDateFormat() { return 'U'; } }