thinkphp5 数据库和模型详解 之4 模型数据处理(核心)和高级用法


1、获取器(可以创造和修改输出的字段)
场景包括:
时间日期字段的格式化输出;
集合或枚举类型的输出;
数字状态字段的输出;
组合字段的输出;
//获取模型的对象属性的时候驼峰法和小写命名方式都可以取到值
//获取器方法的第二个参数表示当前数据对象的所有数据
protected function getUserTitleAttr($value,$data)
{
return $data['name'] . ':' . $data['nickname'];
}
//如果user_title存在时,该数据就会被修改输出;不存在时,该数据就属于被添加的数据,依然可以被输出
$user = User::get(1);
echo $user->user_title;


2、修改器
修改器的使用场景和读取器类似:


时间日期字段的转换写入;
集合或枚举类型的写入;
数字状态字段的写入;
某个字段涉及其它字段的条件或者组合写入;
定义了修改器之后会在下列情况下触发:


模型对象赋值;
调用模型的data方法,并且第二个参数传入true;
调用模型的save方法,并且传入数据;
显式调用模型的setAttr方法;
定义了该字段的自动完成;
//这里传入的data可能已经经过了其它的修改器操作,并非原始的数据
//和读取器不同,修改器的属性必须是数据表中存在的字段,否则修改器的值仅仅能作为数据辅助作用。
protected function setUserTokenAttr($value, $data)
{
return md5($data['name'] . $data['birthday']);
}
3、自动时间字段
//在系统自动时间字段之外的其它时间字段,如果需要自动格式输出,可以设置类型转换
// 开启时间字段自动写入
    //protected $autoWriteTimestamp = true; 
// 开启时间字段自动写入 并设置字段类型为datetime
    protected $autoWriteTimestamp = 'datetime'; 
   // 定义时间字段名
    protected $createTime = 'create_at';
    protected $updateTime = 'update_at';  
4、数据类型转换
//自动时间字段写入只支持创建时间和更新时间的自动写入和格式化读取,如果你的模型有其它时间字段的话,则可以通过设置类型转换来完成
 protected $type = [
'birthday'  =>  'datetime:Y/m/d',
];  
类型转换支持的类型设置包括:
integer
设置为integer(整型)后,该字段写入和输出的时候都会自动转换为整型。
float
该字段的值写入和输出的时候自动转换为浮点型。
boolean
该字段的值写入和输出的时候自动转换为布尔型。
array
如果设置为强制转换为array类型,系统会自动把数组编码为json格式字符串写入数据库,取出来的时候会自动解码。
object
该字段的值在写入的时候会自动编码为json字符串,输出的时候会自动转换为stdclass对象
serialize
指定为序列化类型的话,数据会自动序列化写入,并且在读取的时候自动反序列化。
json
指定为json类型的话,数据会自动json_encode写入,并且在读取的时候自动json_decode处理。
timestamp
入时候会自动使用strtotime生成对应的时间戳,输出的时候会自动转换为dateFormat属性定义的时间字符串格式,默认的格式为Y-m-d H:i:s
datetime
写入和读取数据的时候都会自动处理成时间字符串Y-m-d H:i:s的格式
5、数据自动完成
//数据自动完成是依赖修改器的(和3.2版本区别很大),不支持使用函数或者其它回调来自动完成(但可以支持固定值),足见5.0版本是推崇使用修改器。
//定义了数据自动完成后不需要手动设置属性,一旦使用手动设置的话,自动完成就会忽略,以避免产生多次处理的数据混乱。
protected $auto   = ['active_time'];
protected $insert = ['reg_ip', 'status' => 1];
protected $update = []; 
7、数据转换和输出
//数组转换
$user = User::get(1);
if($user) {
    $data = $user->toArray();
}
//我使用的时候提示collection方法未定义,不知道是不是我的tp5版本过低
$list = User::all();
if($list) {
    $list = collection($list)->toArray();
}
//如果设置了模型的数据集返回类型的话
$list = User::all();
$list = $list->toArray();
//当然toArray方法不仅仅只是转换一个数组这么简单,我们可以在转换数据的时候进行个别字段的隐藏和追加,涉及到四个方法:
//前三个方法的参数都是数组


//JSON序列化
除了转换为数组数据外,还支持对模型对象进行JSON序列化,序列化方法为toJson,使用方法和toArray类似,并且调用toJson序列化之前同样支持hidden、visible、append和appendRelationAttr方法。


方法 说明
hidden 设置隐藏的属性
visible 设置输出的属性
append 追加额外的(获取器)属性
appendRelationAttr 追加额外的关联属性
8、模型事件
批量完成(修改器只能针对某个字段进行修改);
支持判断并自动终止模型数据写入操作;
便于统一管理模型数据操作;
不要对一个模型数据同时使用修改器和模型事件
钩子 对应操作 快捷注册方法
before_insert 新增前 beforeInsert
after_insert 新增后 afterInsert
before_update 更新前 beforeUpdate
after_update 更新后 afterUpdate
before_write 写入前 beforeWrite
after_write 写入后 afterWrite
before_delete 删除前 beforeDelete
after_delete 删除后 afterDelete










高级用法


1、条件查询(内部)
//查询操作应当是静态调用,更新和删除操作则是动态方法调用
//模型查询的原则应当是每个模型对象实例操作一个唯一记录,对于数据集来说这个原则也不变,只是每个数据集对象实例则包含多个模型对象实例而已
// 查询单个记录
$this->where('name', 'thinkphp')->find();
// 调用动态查询方法
$this->getByName('thinkphp');
// 查询数据集
$this->where('id', '>', 0)->limit(10)->order('id desc')->select();
// 删除数据
$this->where('status', 0)->delete();
2、查询范围
//对于一些常用的查询条件,我们可以事先定义好,以便快速调用
//和其他链式查询的时候,查询范围方法必须首先被调用
// 全局查询范围,无需显式
protected static function base($query)
{
// 查询状态为1的数据
$query->where('status', 1);
}
// status查询
protected function scopeStatus($query,$status = '')
{
$query->where('status', $status);
}
$users = User::scope('status','1')->all();//查询范围的方法的第一个参数必须是查询对象,并且支持多个额外参数
$users = User::scope('email,status')->all();//email,status分别是两个查询范围
// 关闭全局查询范围
User::useGlobalScope(false)->get(1);
3、字段过滤
// 获取当前用户对象
$user = User::get(request()->session('user_id'));
// 只允许更新用户的nickname和address数据
$user->allowField(['nickname', 'address'])
    ->data(requst()->param(), true)
    ->save()
// 只允许更新数据表字段数据
$user->allowField(true)
    ->data(requst()->param(), true)
    ->save();
//不必每次都调用allowField方法,我们可以直接在模型类里面设置field属性
 protected $field = ['name', 'nickname', 'email', 'address'];
4、只读字段
//有些数据字段在写入以后就不允许被更改
 protected $readonly = ['name','email'];
5、软删除
//对数据频繁使用删除操作会导致性能问题,因此不推荐直接物理删除数据,而是用逻辑删除替代(软删除)
//为了配合软删除功能,你需要在数据表中添加delete_time字段,ThinkPHP5的软删除功能使用时间戳类型(数据表默认值为Null),用于记录数据的删除时间。
use think\Model;
use traits\model\SoftDelete;


class User extends Model
{
    use SoftDelete;
}
// 软删除
User::destroy(1);
// 真实删除
User::destroy(1,true);
$user = User::get(1);
// 软删除
$user->delete();
// 真实删除
$user->delete(true);
//默认情况下查询的数据不包含软删除数据,如果需要包含软删除的数据,可以使用下面的方式查询:


User::withTrashed()->find();
User::withTrashed()->select();
如果仅仅需要查询软删除的数据,可以使用:


User::onlyTrashed()->find();
User::onlyTrashed()->select();
6、自定义查询类















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

InterestingFigure

迈克 Let's Go

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值