Eloquent ORM
介绍
Laravel包含的Eloquent ORM提供了处理数据库的一套优美、简易的ActiveRecord实现。每个数据表有一个与之对应的模型来操作数据表。
开始之前,确认你配置好了app/config/database.php中的数据库连接。
基本用法
首先,让我们创建一个Eloquent模型,默认在app/models文件夹下,你也可以在composer.json文件里随意指定它的位置,只要确保被自动加载。
定义Eloquent模型
class User extends Eloquent{}
注意,我们并没有特意指定这个模型使用的数据表。其实这个类名的小写和复数就是默认的数据表,除非你特意指定。上面User模型对应的数据表为users,若需要自定义表名,在这个模型类中添加protected的属性$table即可:
class User extends Eloquent{
protected $table = 'my_users';
}
- 注意:Eloquent默认假设每个表有一个名为
id的主键,你可以定义primaryKey属性来覆盖它。同样地,使用模型时用到的数据库连接,你也可以定义connection属性来覆盖它。
一旦模型被定义,你就可以获取和创建数据表记录。注意,默认你需要给数据表指定updated_at和created_at列,如果你希望自动更新,设置$timestamps属性为false;
获取所有数据
$users = User::all();
通过主键来获取一条记录
$user = User::find(1);
var_dump($user->name);
- 注意:所有查询生成器的方法,Eloqunet模型也可以使用。
通过主键获取一条数据,失败抛出异常
有时候你希望模型未找到时抛出一个异常,这样就可以用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);
});
query使用Eloquent模型
$users = User::where('votes', '>', 100)->take(10)->get();
foreach ($users as $user)
{
var_dump($user->name);
}
Eloquent聚合
你也可以使用查询生成器的聚合方法:
$count = User::where('votes', '>', 100)->count();
如果你不能通过查询生成器来生成query,你可以使用whereRaw:
$users = User::whereRaw('age > ? and votes = 100', array(25))->get();
拆分查询
若需要处理大量(数以千计)的Eloquent记录,使用chunk方法可以防止吃掉太多的内存:
User::chunk(200, function($users)
{
foreach ($users as $user)
{
//
}
});
第一个参数200即时你每个chunk处理的记录数。闭包回调参数$users是数据库查询的记录,查询完成后自动调用。
指定某个query的数据库链接
使用on方法可以指定某个数据库连接以查询这个query
$user = User::on('connection-name')->find(1);
批量赋值(Mass Assignment)
创建模型后,我们可以传递一个属性数组给模型构造器。这些属性数组通过Mass Assignment赋值给这个模型。虽然非常方便,但是,盲目的赋值可能会有安全的隐患。如果用户可以随意的传递输入,就可以随意更改模型的属性。出于这个考虑,所有的模型会防范批量赋值。
开始前,需要给模型设置fillable 和 guarded属性:
给模型定义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中的字段可能被更新。
阻止批量赋值里的所有属性
上例中,id和password属性不能批量赋值,而其他的可以。若想阻止所有属性:
protected $guarded = array('*');
插入、更新、删除
添加一条记录
$user = new User;
$user->name = 'John';
$user->save();
- 注意:通常情况下,Eloquent模型有自增键。如果你需要指定自己的,在模型中设置
incrementing属性为false。
你可以使用create方法,使用一行代码就可以创建一个新的模型。create方法会返回插入模型的实例。当然了,你必须指定属性fillable或者guarded,因为所有的Eloquent模型都防范批量赋值。
使用自增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'));
获取模型后更新
你可以先获取一个模型实例,改变它的属性值,然后用save方法来更新:
$user = User::find(1);
$user->email = '[email protected]';
$user->save();
保存模型及关系
若需要保存一个模型实例及所有关系,可以使用push方法:
$user->push();
你也可以以query的方式来执行udpate
$affectedRows = User::where('votes', '>', 100)->update(array('status' => 2));
- 注意:当你使用Eloquent的查询生成器时,不会激活任何的事件
删除存在的模型实例
调用delete方法:
$user = User::find(1);
$user->delete();
通过主键值来删除模型实例
User::destroy(1);
User::destroy(array(1, 2, 3));
User::destroy(1, 2, 3);
当然你可以在一系列的模型实例上执行一个删除query:
$affectedRows = User::where('votes', '>', 100)->delete();
只更新模型的timestamps字段
若纸箱更新模型的timestamps字段,使用touch方法:
$user->touch();
软删除
当执行软删除时,并不会真正的从数据库删除数据,而是在记录的deleted_at时间戳进行设置。使用它需要在模型里应用SoftDeletingTrait:
user Illuminate\Database\Eloquent\SoftDeletingTrait
class User extends Eloquent{
use SoftDeletingTrait;
protected $dates = ['deleted_at'];
}
数据表添加deleted_at字段后,就可以在数据库迁移时用softDeletes方法:
$table->softDeletes();
现在在模型上使用delete方法时,对应字段deleted_at值会设置为当前时间戳。当查询一个使用了软删除的模型时,“软删除”的数据不会包含到结果中。
强制软删除数据显示到结果集中
若想强制显示软删除数据,query时使用withTrashed方法:
$user = User::withTranshed()->where('account_id', 1)->get();
withTranshed方法在关联时依然有效:
$user->posts()->withTrashed()->get();