ThinkPHP6.0学习笔记-模型操作 (4)

前缀scope ,后缀自定义,在调用时吧后缀当做参数即可。

public function scopeMale($query) { $query->where(\'gender\',\'男\') ->field(\'id,username,gender,email\') ->limit(5); } $user = model\UserModel::scope(\'male\')->select(); return "<hr>".Db::getLastSql()."<hr>".$user; public function scopeEmail($query, $value) { $query->where(\'email\',\'like\',\'%\'.$value.\'%\'); } $user = UserModel::scope(\'email\',\'xiao\')->select(); return "<hr>".Db::getLastSql()."<hr>".$user;

scope() 的第一个参数是调用的封装方法,第二个参数是封装方法可以接收的数据

支持多个查询封装方法连缀调用

$user = UserModel::scope(\'email\',\'xiao\') ->scope(\'price\',80) ->select(); return "<hr>".Db::getLastSql()."<hr>".$user;

在使用查找范围scope()后,指定使用find() select()查询;

在模型类中的查询封装方法中可以使用包括修改器、获取器等在内的模型操作方法。

public function getGenderAttr($value,$data) { $gender = [\'男\'=>\'纯爷们\',\'女\'=>\'小姑娘\']; return $gender[$value]; } public function scopeMale($query) { $query->where(\'gender\',\'男\') ->field(\'id,username,gender,email\') ->limit(5); } 全局查找范围

支持在模型中设置globaScope属性,定义全局查找范围

class User extends Model { // 定义全局的查询范围 protected $globalScope = [\'status\']; public function scopeStatus($query) { $query->where(\'status\',1); } }

然后,执行下面的代码:

$user = User::find(1);

最终的查询条件会是

status = 1 AND id = 1

如果需要动态关闭所有的全局查询范围,可以使用:

// 关闭全局查询范围 User::withoutGlobalScope()->select();

可以使用withoutGlobalScope方法动态关闭部分全局查询范围。

User::withoutGlobalScope([\'status\'])->select(); 模型搜索器

搜索器用于封装字段或搜索标识的表达式,类似查找范围

一个搜索器对应模型的一个特殊方法

命名规范

search[FieldName]Attr()

User模型定义name字段和时间字段的搜索器,可以使用:

class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where(\'name\',\'like\', $value . \'%\'); } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime(\'create_time\', $value[0], $value[1]); } }

然后,我们可以使用下面的查询

User::withSearch([\'name\',\'create_time\'], [ \'name\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1 ])->select();

最终生成的SQL语句类似于

SELECT * FROM `think_user` WHERE `name` LIKE \'think%\' AND create_time` BETWEEN \'2018-08-01 00:00:00\' AND \'2018-08-05 00:00:00\'

可以看到查询条件中并没有status字段的数据,因此可以很好的避免表单的非法查询条件传入,在这个示例中仅能使用name和create_time条件进行查询。

事实上,除了在搜索器中使用查询表达式外,还可以使用其它的任何查询构造器以及链式操作。

例如,你需要通过表单定义的排序字段进行搜索结果的排序,可以使用

class User extends Model { public function searchNameAttr($query, $value, $data) { $query->where(\'name\',\'like\', $value . \'%\'); if (isset($data[\'sort\'])) { $query->order($data[\'sort\']); } } public function searchCreateTimeAttr($query, $value, $data) { $query->whereBetweenTime(\'create_time\', $value[0], $value[1]); } }

然后,我们可以使用下面的查询

User::withSearch([\'name\',\'create_time\', \'status\'], [ \'name\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1, \'sort\' => [\'status\'=>\'desc\'], ]) ->select();

最终查询的SQL可能是

SELECT * FROM `think_user` WHERE `name` LIKE \'think%\' AND `create_time` BETWEEN \'2018-08-01 00:00:00\' AND \'2018-08-05 00:00:00\' ORDER BY `status` DESC

你可以给搜索器定义字段别名,例如:

User::withSearch([\'name\'=>\'nickname\',\'create_time\', \'status\'], [ \'nickname\' => \'think\', \'create_time\' => [\'2018-8-1\',\'2018-8-5\'], \'status\' => 1, \'sort\' => [\'status\'=>\'desc\'], ]) ->select();

搜索器通常会和查询范围进行比较,搜索器无论定义了多少,只需要一次调用,查询范围如果需要组合查询的时候就需要多次调用

模型数据集

数据集直接继承collection类,和数据的数据集方式一样、操作一样。

参照官方技术文档

模型自动时间戳

系统支持自动写入创建和更新的时间戳字段(默认会关闭),具体配置方法:

全局开启:在database.php文件中修改auto_timestamp为truely

在模型类中单独开启自动时间戳:$autoWriteTimestamp

class User extends Model { protected $autoWriteTimestamp = true; }

也或者单独关闭自动时间戳

class User extends Model { protected $autoWriteTimestamp = false; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzdsyy.html