静态软删除:destroy( )
1. 功能:软删除符合条件的数据表记录。该方法与delete可以实现同样的功能,但是调用方式不一样。因为这是一个静态方法,不需要模型对象,直接用模型类静态调用即可。
2. 源码分析:源码位置:/thinkphp/library/traits/model/SoftDelete.php我们将源码解读全部写在注释中,请仔细看:/**
* 删除记录/软删除
* 该方法同样覆盖父类Model同名方法,用于静态调用
* @access public
* @param mixed $data 主键列表 支持闭包查询条件
* @param bool $force 是否强制删除
* @return integer 成功删除的记录数
*/public static function destroy($data, $force = false){ //实例化当前调用该方法的模型类:Staff.php//static():可以理解为静态方法中的$this$model = new static(); // 等价于: new Staff();//获取数据库查询对象,db()方法不在SoftDelete类中,这是调用Model类方法实现的$query = $model->db();//判断参数是否是数组,并且还是得关联数组if (is_array($data) && key($data) !== 0) {//设置查询条件,保存在Query对象的$options[]属性中$query->where($data);$data = null; //清空查询条件,为后面的连贯方法做准备} elseif ($data instanceof \Closure) { //判断条件是闭包call_user_func_array($data, [ & $query]); //调用闭包函数$data = null; //清空条件} elseif (is_null($data)) { //如果无参数传入return 0; 返回假:0}//下面是对查询获取到的结果集进行处理$resultSet = $query->select($data);$count = 0; //计数器清零($count存放受影响的记录数量)if ($resultSet) { //如果结果集存在foreach ($resultSet as $data) { //遍历该结果集$result = $data->delete($force); //逐条删除数据$count += $result; //计数器累加}
}return $count; //返回删除记录的数量}特别注意:$result = $data->delete($force);中的delete($force),就是定义在SoftDelete.php类中的delete方法(软删除当前实例对象),并非数据库Query类中的delete方法,一定要注意呀~~~
3. 参数与返回值参数序号参数说明1$key / 主键删除单条记录,与delete方法类似
2$array / 主键列表删除多条记录,主键列表放在数组中
3$where / 条件表达式支持所有的查询表达式
3$closure / 闭包函数闭包函数中仅支持使用where方法返回值:软删除的记录数量。
4. 实例演示准备工作:先创建自定义模型类:Staff.php<?php
namespace app\index\model;
use think\Model;
use traits\model\SoftDelete;class Staff extends Model{//引入SoftDelete类use SoftDelete;
}Staff.php 类仅一条语句就可以了:use SoftDelete;。
一、根据主键或主键列表软删除该操作非常简单,与前面学习的过的Model类的delete完全一样。我们快速带过
任务1:软删除主键id = 1002 的记录关键语句:delete(条件,false) 中的false可省略,但建议写上,以便与硬删除有明显区别。Staff::destroy(1002,false);
任务2:软删除主键id = 1002,1003,1004 的记录关键语句:主键列表,要写一个索引数组中Staff::destroy([1002,1003,1004],false);注意:每次执行完成,请重置delete_time,为下例做准备://将所有软删除数据手工恢复update tp5_staff set delete_time = null;
二、根据查询条件软删除数据
任务3: 软删除工资salary大于5000的员工:查询条件以数组形式提供控制器:Index.php<?phpnamespace app\index\controller;use app\index\model\Staff;class Index{public function index(){ //软删除salary > 5000的记录 $affected = Staff::destroy(['salary'=>['>',5000]],false);echo $affected ? '成功软删除'.$affected.'条记录!' : '软删除失败'; //创建闭包查询函数 $closure = function ($query){$query -> field('id,name,delete_time');
};//执行查询 $result = Staff::all($closure); //这里不用all(),用selectd()也一样//遍历结果对象数组foreach ($result as $data){
dump($data->getData());
}
}
}
任务4:软删除表中年龄大于30,并且工资在4000到5000之间的记录该任务我们用闭包函数来实现,重点讲解:我们先查看一下表中数据:
控制器:Index.php<?phpnamespace app\index\controller;use app\index\model\Staff;class Index{public function index(){ //创建删除条件:闭包$where = function ($query){$query -> where('age','>',30)
-> where('salary','between',[4000,5000]);
};//软删除age>30 AND salary在4000到5000之间的记录 $affected = Staff::destroy($where,false);echo $affected ? '成功软删除'.$affected.'条记录!' : '软删除失败'; //创建闭包查询函数 $closure = function ($query){$query -> field('id,name,delete_time');
};//执行查询 $result = Staff::all($closure);//遍历结果对象数组foreach ($result as $data){
dump($data->getData());
}
}
}运行结果如下:成功软删除1条记录!array(3) {
["id"] => int(1001)
["name"] => string(6) "郭靖"
["delete_time"] => NULL}array(3) {
["id"] => int(1002)
["name"] => string(6) "黄蓉"
["delete_time"] => NULL}array(3) {
["id"] => int(1006)
["name"] => string(6) "杨康"
["delete_time"] => NULL}再看一下表中情况:
5. 总结看过源码我们知道,destroy方法内部还是调用本类的delete方法执行的。在完成任务的前提下,我推荐首选静态方法,毕竟静态方法运行效率远高于普通方法。