使用Model访问数据
-
如何定义一个和数据表匹配的模型
class User extends Model
-
Model会自动对应数据表,并有一套自己的命名规则,Model类需要去除表前缀(如有),采用驼峰式命名且首字母大写,如
- tp_user => User
- tp_user_type => UserType
-
通过建立
Model
获取数据的方法是在app
下建立model
文件夹,创建文件名与数据库真实表名具有一致或映射(比如前缀)关系的模型文件,如数据库中表名是User可创建User.php并使其继承think\Model
,见代码
namespace app\model;
use think\Model;
class User extends Model
{
// 不是忘写了,是不用写
}
接口访问的是Controller,因此真正运行并返回数据要在控制器代码中,使用如下方法访问获取数据
// 控制器中的使用方法
// 引用自定义的 User Model
use app\model\User
public function getUser()
{
return json(User::select());
}
- 在Model里添加预定义的属性可提供高级功能,如
protected $connection = \'mysql_backup_2\'
指定要是用的连接名称(连接名在config\database.php中定义)protected $name = \'user\'
指定当前 model 所映射的数据表全名,忽略框架命名规则,适用于model类名喜欢自定义不遵守框架默认约定时使用。如与user表对应的model类文件命名不按默认规则命名为app\model\User.php而是app\model\UserModel.php
namespace app\model;
use think\Model;
class UserModel extends Model
{
// 明确指示本类 model 映射表名为 user
protected $name = \'user\';
}
protected $table
设置映射表,结果类似$name
protected static function init()
初始化函数
使用Model新增数据
$user = new User();
$user->username = \'Tom\';
$user->email = \'tom@user.com\';
// 实例化的 model 对象且无主键作为参数时,执行 save() 表示新增数据
$user->save();
也可以将数据以键值对方式组成数组作为参数传递给save方法,如$user->save([username=>\'Tom\', email=>\'tom@user.com\']);
saveAll([])
批量allowField([])
设定允许写入的字段replace()->save()
MySQL及其它支持replace的能力即存在就更新不存在就插入,返回 true 或 false
$access = new OperatorAccess();
$access->uid = $userId;
$access->access_code = $accessCode;
return $access->replace()->save();
User::create( $data, $allowFields, $isReplaced)
使用静态方法创建数据,$data
新增数据组成的数组,必选,$allowFields
允许写入的字段,可选,$isReplaced
是否replace写入,默认false
更新
- 最简单的更新:
model::where()->save()
,返回受影响的行数 replace()->save()
记录存在则更新,否则将新增,返回 true 或 false
字段设置
model 的数据字段和表字段是对应的,默认会自动获取全部,包括字段名和字段类型。自动获取会导致增加一次查询,因此在模型中进行主动配置字段信息会减少至少一次IO,通过设置protected $schema
明确定义字段信息
protected $schema = [
\'id\' => \'int\',
\'username\' => \'string\',
\'create_time\' => \'datetime\'
]
框架提供一个命令可以缓存模型对应数据表的字段信息,运行命令将字段信息缓存在runtime/schema
下
> cd 项目目录下
> php think optimize:schema
将缓存文件内容复制到 model 中,默认情况下字段缓存是关闭状态,在config/database.php中的connections配置部分开启fields_cache=true
获取器 getFieldAttr()
对查询数据进行自定义加工,如表示状态经常用int但返回结果希望是string,类似这样的需求就可以应用获取器。在 model 中定义其行为,在 controller 中进行调用
// model 类中创建 public 方法
// 方法命名有预定义规则,注意查看手册
public function getStatusAttr($value){
$arr = [-1=>\'删除\', 0=>\'禁用\', 1=>\'正常\'];
return $arr[$value];
]
// controller 中调用
$user = User::find(19);
return $user->status;
getFieldAttr($value, $data)
第二个参数是完整数据而非单个字段,此时可以在 model 中创建虚拟字段修改器,增强获取器返回的数据的丰富程度
// model 类中创建 public 方法
// 方法命名有预定义规则,注意查看手册
public function getNothingAttr($value, $data){
$arr = [-1=>\'删除\', 0=>\'禁用\', 1=>\'正常\'];
return $arr[$data[\'status\']];
}
// controller 中调用
$user = User::find(19);
return $user->nothing;
WithAttr() 实现控制端动态获取器
getFieldAttr()
需要提前写好,是静态的,使用 withAttr($colName, $func)
闭包实现自定义动态获取,如同时有定义,动态获取器优先级更高
// 示例一
$user = User::withAttr(\'email\', function ($value) {
return strtoupper($value);
})->select();
//示例二
$user = User::withAttr(\'status\', function ($value) {
$arr = [-1=>\'删除\', 0=>\'禁用\', 1=>\'正常\'];
return $arr[$value];
})->select();
setAttr()修改器
修改器作用是对模型设置的对象的值进行IO前的处理,如新增数据时对数据进行格式化、过滤、转换等,模型修改器命名规则是setFieldAttr
,模型方法新增数据时会调用修改器,修改更新也会触发修改器,模型修改器只对模型方法有效,调用数据库方法则无效。
// model 类中创建 public 方法
// 方法命名有预定义规则,注意查看手册
pubilc function setEmailAttr($value){
return strtoupper($value);
}
// controller 部分
// 通过模型方法创建数据将自动调用修改器,新增数据的 email 字段将会被修改为大写字母
$user = User::create([...]);