模型查询和数据库查询方法的区别在于 模型中的查询的数据在获取时经过获取器处理 及对象化的获取方式
模型查询除了使用自身的查询方法 可用数据库的查询构造器 返回模型对象实例
但如果直接调用查询对象的方法 IDE可能无法完成自动提示
获取单个数据
// 取出主键为1的数据 $user = User::get(1); echo $user->name;// 查询构造器查询满足条件的数据 $user = User::where('name', 'think')->find(); echo $user->name;
模型用get
还是find
方法查询 返回当前模型的对象实例
除了获取模型数据外 还可以使用模型的方法
V5.1.5+
模型getOrFail
用于查询 当查询的数据不存在的时候抛出ModelNotFound
异常
模型内部获取模型数据 不要使用
$this->name
的方式来获取数据
请使用$this->getAttr('name')
获取多个数据
// 根据主键获取多个数据 $list = User::all('1,2,3');// 或使用数组 $list = User::all([1,2,3]);// 数据集遍历操作 foreach($list as $key=>$user){ echo $user->name; }
查询构造器:
// 使用查询构造器查询 $list = User::where('status', 1)->limit(3)->order('id', 'asc')->select(); foreach($list as $key=>$user){ echo $user->name; }
查询构造器方式的查询支持更多的连贯操作 包括排序、数量限制等
自定义数据集对象
模型all
或select
方法返回包含多个模型实例的数据集对象(默认为think\model\Collection
)
支持在模型中单独设置查询数据集的返回对象的名称
use thinkModel; class User extends Model{// 设置返回数据集的对象名 protected $resultSetType = 'app\common\Collection'; }
resultSetType
属性用于设置自定义的数据集使用的类名 该类应当继承系统的think\model\Collection
类
查询构造器
模型中可调用数据库的链式操作和查询方法 充分利用数据库的查询构造器的优势
User::where('id',10)->find(); User::where('status',1)->order('id desc')->select(); User::where('status',1)->limit(10)->select();
查询构造器直接使用静态方法调用 无需实例化模型
获取某个字段或某个列的值
// 获取某个用户的积分 User::where('id',10)->value('score');// 获取某个列的所有值 User::where('status',1)->column('name');// 以id为索引 User::where('status',1)->column('name','id');
value
和column
方法返回的不再是个模型对象实例
纯粹的值或某个列的数组
动态查询
数据库的动态查询方法
// 根据name字段查询用户 $user = User::getByName('think'); // 根据email字段查询用户 $user = User::getByEmail('think@qq.com');
聚合查询
模型中调用数据库的聚合方法查询
User::count(); User::where('status','>',0)->count(); User::where('status',1)->avg('score'); User::max('score');
数据分批处理
模型对返回的数据分批处理
在处理大数据时非常有用
User::chunk(100,function($users) { foreach($users as $user){// 处理user模型对象} });
使用游标查询
模型用数据库的cursor
方法游标查询 返回生成器对象
foreach(User::where('status', 1)->cursor() as $user){ echo $user->name; }
user
变量是个模型对象实例
查询缓存
get
和all
方法查询缓存 直接在第二个参数传入true表示开启查询缓存
$user = User::get(1,true);$list = User::all('1,2,3',true);
要设置缓存标识 则必须在第三个参数传入缓存标识
$user = User::get(1,'','user');$list = User::all('1,2,3','','user_list');
主库读取
分布式数据库 写入数据后立刻进行该数据的读取 会导致数据读取失败 原因是数据库同步尚未完成
规范的解决方案是在写入数据后 不马上从从库读取 而应该调用master
方法读取主库
$user = new User; $user->name = 'think'; $user->email = 'think@qq.com'; $user->save();// 从主库读取数据 $user->master()->get($user->id);
或对关键的逻辑启用事务 在事务中的数据库操作都是基于主库的
V5.1.12+
开始 在数据库配置文件中设置
// 主库写入后从主从库读取 'read_master'=> true
设置开启后 模型有写入操作 那么该请求后续的同个模型的读操作都会自动从主库读取。
如果只需要对某个模型生效 在完成主库写入操作后 执行下模型类的readMaster
方法
$user = new User; $user->name = 'think'; $user->email = 'think@qq.com'; $user->save();// 从主库读取数据 $user->readMaster(true)->get($user->id);
上述设置和方法仅对模型查询有效
直接调用Db类查询无效
最佳实践
最佳实践原则
模型外部使用静态方法进行查询
内部使用动态方法查询 包括使用数据库的查询构造器。
模型的查询始终返回对象实例 但可以和数组一样使用
尊贵的董事大人
英文标题不为空时 视为本栏投稿
需要关键字 描述 英文标题