Thinkphp5中的软删除

19 篇文章 1 订阅
前言:在实际项目中,对数据频繁使用删除操作会导致性能问题,软删除的作用就是把数据加上删除标记,而不是真正的删除,同时也便于需要的时候进行数据的恢复。
1.修改或者添加数据库字段
Thinkphp5 中默认的该字段是 delete_time,创建表的时候需要添加字段 delete_time。
例如:创建一个 user_list表。
	CREATE TABLE `user_list` (
  `key` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户表主键key',
  `name` varchar(100) DEFAULT NULL COMMENT '登录用户名',
  `user_name` varchar(100) DEFAULT NULL COMMENT '用户名',
  `delete_time` int(11) unsigned DEFAULT NULL COMMENT '删除时间',
  PRIMARY KEY (`key`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;
其中的字段 delete_time 就是Thinkphp5 中默认的删除字段。
2.自定义删除字段
在 Thinkphp5 中在model类方法中可以自定义所需要的删除字段,不想用 delete_time 做删除字段也可以用其他的字段代替。
	//定义数据表中软删除标记字段
    protected $deleteTime = 'delete_time';//字段名可以自定义。
3.在model类中的使用
自定义一个 model 类 UserlistModel
<?php
namespace app\user\model;
use traits\model\SoftDelete;
use think\Model;

class UserlistModel extends Model
{
    use SoftDelete;
    //定义数据表中软删除标记字段
    protected $deleteTime = 'delete_time';
    //5.1以上版本才有defaultSoftDelete属性,设置软删除字段的默认值,5.0的默认值为NULL
    protected $defaultSoftDelete = 0;
}
4.实际使用
定义好模型后,就可以使用软删除了,下面是软删除的2种使用方式:
//1.通过模型的静态方法
//软删除
UserlistModel::destroy(1);
UserlistModel::destroy(function($query){
    $query->where('key','>',10);
});
UserlistModel::destroy(['status' => 0]);
//真实删除
UserlistModel::destroy(1,true);

//2.查询后调用 delete 方法
$user = UserlistModel::get(1);
//软删除
$user->delete();
//真实删除
$user->delete(true);
默认情况下查询的数据不包含软删除数据,如果需要包含软删除的数据,可以使用下面的方式查询:
//包含软删除的数据
UserlistModel::withTrashed()->find();
UserlistModel::withTrashed()->select();
如果仅仅需要查询软删除的数据,可以使用:
//仅查询软删除的数据
UserlistModel::onlyTrashed()->find();
UserlistModel::onlyTrashed()->select();

注:软删除仅对模型的删除方法有效,如果直接使用数据库的删除方法则无效,例如下面的方式无效(将不会执行任何操作)(只有查询后的模型调用 delete 方法会生效,直接调用 delete 方法的话无法调用模型事件)。

//这种写法无法实现软删除的功能
UserlistModel::where('key',1)->delete();

//这种方式才能是软删除
$user = UserlistModel::where('key',1)->find();
$user->delete();
5.thinkphp官方的SoftDelete trait性能上有些缺陷,改为引入 自定义的SoftDelete trait。
<?php
namespace app\base\model;//可以自定义命名空间
use traits\model\SoftDelete as Base;
trait SoftDelete
{
    //组合核心库中软删除类
    use Base;
    /**
     * 删除记录(重写核心库中destroy方法)
     * @access public
     * @param mixed $data  主键列表(支持闭包查询条件)
     * @param bool  $force 是否强制删除
     * @return integer 成功删除的记录数
     */
    public static function destroy($data, $force = false)
    {
        if (is_null($data)) {
            return 0;
        }
        //包含软删除数据
        $query = (new static())->db(false);
        if (is_array($data) && key($data) !== 0) {
            $query->where($data);
            $data = null;
        } elseif ($data instanceof \Closure) {
            call_user_func_array($data, [ & $query]);
            $data = null;
        }

        $count = 0;
        $name = (new static())->getDeleteTimeField();
        $key = (new static())->getPkField();
        if ($resultSet = $query->field($key)->where($name, 'null')->select($data)) {
            foreach ($resultSet as $data) {
                $result = $data->delete($force);
                $count += $result;
            }
        }
        return $count;
    }

    /**
     * 获取主键字段
     * @access public
     * @param bool $read 是否查询操作(写操作的时候会自动去掉表别名)
     * @return string
     */
    protected function getPkField($read = false)
    {
        $field = property_exists($this, 'pk') && isset($this->pk) ?
        $this->pk :
        'key';
        if (false === $field) {
            return false;
        }
        if (!strpos($field, '.')) {
            $field = '__TABLE__.' . $field;
        }
        if (!$read && strpos($field, '.')) {
            $array = explode('.', $field);
            $field = array_pop($array);
        }
        return $field;
    }
}

使用方法,直接在 model 方法中进行调用。

<?php
namespace app\daba\model;
use app\base\model\SoftDelete;//调用自定义的软删除类
use think\Model;
class UserlistModel extends Model
{
    use SoftDelete;
    protected $name = 'user_list';
    //定义数据表中软删除标记字段
    protected $deleteTime = 'delete_time';
    //5.1以上版本才有defaultSoftDelete属性,设置软删除字段的默认值,5.0的默认值为NULL
    protected $defaultSoftDelete = 0;

    public static function getList()
    {
        return self::onlyTrashed()->select();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值