laravel框架中的ORM模型极大的简化了数据库操做,同时也提升了数据操做安全性。laravel
在laravel框架ORM模型中默认会有三个时间字段,created_at,updated_at,deleted_at,这三个时间字段是框架默认操做,不用另加代码去处理,非赏方便:数据库
如: UserModel::create($insert); ORM模型会自动添加上create_at字段但写入当前时间,而不用咱们本身去添加这个字段,在修改时会加上updated_at,安全
在删除时laravel框架提供两种模式,一个是正常删除,一个是软删除,app
正常删除会直接删除数据库里的记录,一样咱们也不用为表建立deleted_at字段,框架
当使用软删除时,框架不会直接删除数据库里的数据,而是直接写deleted_at指定当前删除时间。ide
注意:当laravel使用了软删除,在每次正常查询时都会添加一个deleted_at is null 的条件,以去掉删除的记录,当前要取出删除的记录则要 UserModel::onlyTrashed()->get();ui
ORM在开发中方便了数据操做,只是在laravel框架中默认的ORM模型这三个时间字段的数据类型是datetime型,并且在软删除模式中deleted_at必须容许为NULL,更要命的是若是咱们修改了字段类型为int型时deleted_at字段也必须容许为NULL,不然软删除会出现没法正常取数据,由于在使用软删除时框架默认添加的条件是deleted_at is NULL为正常数据,在一些数据量大的表中通常时间字段会使用int型,而若是容许为NULL则会影响索引的命中。this
具体的修改有:spa
/**
* 指定时间字符
*
* @param \DateTime|int $value
* @return string
*/
public function fromDateTime($value)
{
return strtotime(parent::fromDateTime($value));
}对象
以上代码是修改字段写入数据库的数据类型为int
若是这个时候咱们想修改这三个字段的名称能够在对应的MODEL类中添加如下代码
const DELETED_AT='delete_at';
const UPDATED_AT='update_at';
const CREATED_AT = 'create_at';
以上处理只能是在没有使用软删除时正常工做,若是使用了软删除则必须重写 SoftDeletingTrait 中的几个方法,而且扩展Illuminate\Database\Eloquent\SoftDeletingScope类
代码以下:
trait SoftDelete{
use SoftDeletingTrait;
/**
* 建立软删除对象
*
* @return void
*/
public static function bootSoftDeletingTrait()
{
static::addGlobalScope(new SoftDeleteScope);
}
/**
* 只获取软删除的记录
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function onlyTrashed()
{
$instance = new static;
$column = $instance->getQualifiedDeletedAtColumn();
return $instance->newQueryWithoutScope(new SoftDeleteScope)->where($column,'>',new Illuminate\Database\Query\Expression('0'));
}
/**
* 获取软删除与正常一块儿的记录
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withTrashed()
{
return with(new static)->newQueryWithoutScope(new SoftDeleteScope);
}
}
class SoftDeleteScope extends Illuminate\Database\Eloquent\SoftDeletingScope{
/**
* 只获取正常数据
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
public function apply(Illuminate\Database\Eloquent\Builder $builder)
{
$model = $builder->getModel();
$builder->where($model->getQualifiedDeletedAtColumn(),'=',new Illuminate\Database\Query\Expression('0'));
$this->extend($builder);
}
/**
* 只获取软删除数据
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
protected function addOnlyTrashed(Illuminate\Database\Eloquent\Builder $builder)
{
$builder->macro('onlyTrashed', function(Illuminate\Database\Eloquent\Builder $builder)
{
$this->remove($builder);
$builder->getQuery()->where($builder->getModel()->getQualifiedDeletedAtColumn(),'>',new Illuminate\Database\Query\Expression('0'));
return $builder;
});
}
/**
* 去掉软删除条件
*
* @param array $where
* @param string $column
* @return bool
*/
protected function isSoftDeleteConstraint(array $where, $column)
{
return $where['type'] == 'Basic' && $where['operator']=='=' && $where['value']=='0' && $where['column'] == $column;
}
}
说明:
SoftDelete 是重写 SoftDeletingTrait 中的部分方法,只要咱们建立的MODEL使用了 use SoftDelete;
就能把原来的deleted_at字段彻底修改成int类型,而且不容许为null。
SoftDeleteScope类只是为了修改在软删除时添加的deleted_at is null的条件。
到这里只要咱们建立的MODEL继承于Eloquent而且在类中添加use SoftDelete;重写fromDateTime方法就可使用int类型的时间字段
固然也能够在Eloquent与Model中间再添加一个类用于重写fromDateTime方法,能够实现全部的model都使用int类型的时间字段