ThinkPHP---辅助方法
【三】Tp常见的辅助方法
原生SQL语句里除了目前所使用的基本操作增删改查,还有类似于group、where、order、limit等这样的字句。
ThinkPHP封装了相应的子句方法:封装的方法都在父类模型Model.class.php
where 表示限制查询的条件
limit 限制输出的条数
filed 限制输出的字段,也就是select id,name,age等类似语句
注意:下面两个方法在父类模型中不存在,方法不存在会走魔术方法__call(),利用__call()方法实现一些特殊的Model方法,而group和order在链操作方法列表,经过__cal()方法调用。实现相应方法。除此外还有alias(别名),having(限制查询条件),distinct(去重),filter(过滤)。
order 字段排序
group 按照指定字段进行分组查询
下面依次介绍:
(1)where
作用:限制查询条件
原生sql语句:select 字段 from 表名 where 条件;
ThinkPHP中封装的where方法:
$model -> where(条件表达式);//ThinkPHP条件表达式支持字符串形式('id=1'),也支持数组形式(array(id=>'1')),推荐使用字符串形式
$model -> CURD操作;
案例:使用where查询表中数据('id>20')
原生SQL语句:
select * from sp_dept where id>20;
ThinkPHP的where方法:
public function test(){
//实例化模型
$model = M('dept');
//where查询
$model -> where('id>20 and id<22');
//验证 dump($model);die;
$data = $model -> select();//这里可以不添加参数,上面输出$model验证下
dump($data);
}
验证$model输出如下:
["options":protected] => array(1) {
["where"] => array(1) {
["_string"] => string(5) "id>20 id<22"
}
}
底层父类模型:
// 分析表达式
$options = $this->_parseOptions($options);
跟踪信息的sql:SELECT * FROM `sp_dept` WHERE ( id>20 and id<22) [ RunTime:0.0000s ]
回顾:在MySQL里除了where外,having也可以限制查询
面试题:where和having都可以限制查询条件,区别是什么?
where表示限制查询条件,要求查询字段必须是数据表中存在的字段;而having要求结果集(查询出的数据结果)中存在的字段
(2)limit方法
限制输出的条数(典型应用,数据的分页)
原生SQL语句:
select 字段 from 表名 where 条件 limit 限制的条数;
ThinkPHP中封装的limit方法:
①$model -> limit(n); //n为大于0的数字,表示输出表中的前n行
②$model -> limit(起始位置,偏移量); //表示从起始位置开始,往后查询指定长度的记录数。实际使用中还支持$model -> limit('起始位置,偏移量')的写法
案例:使用limit实现查询表中的数据限制
①查询前n条
public function test(){
//实例化模型
$model = M('dept');
//限制记录
$model -> limit(2);//查询前2条
$data = $model -> select();
dump($data);
}
跟踪信息的SQL语句:SELECT * FROM `sp_dept` LIMIT 2 [ RunTime:0.0000s ]
②查询带偏移量的形式
public function test(){
//实例化模型
$model = M('dept');
//限制记录
$model -> limit(2,2);//查询从第三条开始的两条记录
$data = $model -> select();
dump($data);
}
跟踪信息SQL语句:SELECT * FROM `sp_dept` LIMIT 2,1 [ RunTime:0.0000s ]
注意:limit从0开始,所以如果想从第3条开始,传入2即可
(3)field方法
作用:限制输出的结果集字段
类似于:原生SQL的select id,name,age
语法:
$model -> field('字段1,字段2...字段n[as 别名,支持别名]'); //参数就是select之后from之前的一串字符串
案例:限制结果集输出,只显示id,name信息
原生sql:
select id,name from sp_dept;
ThinkPHP封装的field方法:
public function test(){
//实例化模型
$model = M('dept');
//条件限制
$model -> where('id>20 and id<22');
//结果集记录限制
$model -> field('id,name');
//执行查询
$data = $model -> select();
dump($data);
}
跟踪信息SQL语句:SELECT `id`,`name` FROM `sp_dept` WHERE ( id>20 and id<22 ) [ RunTime:0.0010s ]
(4)order方法
作用:按照指定的字段进行指定规则排序
原生SQL语法里:
order by 字段 排序规则(升序ase/降序desc)
ThinkPHP封装的语法:
$model -> order('字段名 排序规则');
案例:使用order方法,查询部门表中数据,并且按照id进行降序排列
原生SQL语句
select * from sp_dept order by id desc;
ThinkPHP方法
public function test(){
//实例化模型
$model = M('dept');
$model -> where('id>20');
//按照id降序排序
$model -> order('id desc');
//查询
$data = $model -> select();
dump($data);
}
跟踪信息SQL语句:SELECT * FROM `sp_dept` WHERE ( id>20 ) ORDER BY id desc [ RunTime:0.0000s ]
(5)group方法
作用:用于分组查询
ThinkPHP封装的group方法
$model -> group('字段名');//按照字段名进行分组,相当于group by 字段名
案例:查询部门表,查询出部门名称和出现的次数
原生SQL
select name,count(*) as count from sp_dept group by name;
ThinkPHP的group辅助方法
因为上面使用了限制字段和分组查询,所以只靠group方法,无法实现。需要配合field方法配合
public function test(){
//实例化模型
$model = M('dept');
//指定字段和分组
$model -> group('name');
$model -> field('name,count(*) as count');
// dump($model);die;
//查询
$data = $model -> select();
dump($data);
}
输出结果:
array(3) {
[0] => array(2) {
["name"] => string(4) "tony"
["count"] => string(1) "1"
}
[1] => array(2) {
["name"] => string(9) "技术部"
["count"] => string(1) "3"
}
[2] => array(2) {
["name"] => string(9) "新天剑"
["count"] => string(1) "2"
}
}
跟踪信息SQL语句:SELECT `name`,count(*) as count FROM `sp_dept` GROUP BY name [ RunTime:0.0010s ]
【四】连贯操作
(1)简介
将辅助方法全部写在一行上的写法为连贯操作
语法:$model -> where() -> limit() ->order() -> field() -> select{}
中间标红的即为辅助方法
辅助方法顺序:在连贯操作里,没有顺序要求。只要模型在头部,CURD方法在尾部即可
案例:连贯操作改写
public function test(){
//实例化模型
$model = M('dept');
//连贯操作查询
$data = $model -> field('name,count(*) as count') ->group('name')-> select();
dump($data);
}
问题:为什么辅助方法可以写在一行上?
查看分析父类模型,例如field()返回的都是对象本身$model
/**
* 指定查询字段 支持字段排除
*/
public function field($field,$except=false){
if(true === $field) {// 获取全部字段
$fields = $this->getDbFields();
$field = $fields?:'*';
}elseif($except) {// 字段排除
if(is_string($field)) {
$field = explode(',',$field);
}
$fields = $this->getDbFields();
$field = $fields?array_diff($fields,$field):$field;
}
$this->options['field'] = $field;
return $this;
}
原因就是每一个辅助方法最后的返回值都是$this,而$this是指当前模型类。由模型类去调用后续的辅助方法,这个是行得通的。
之所以将select()等具体的CURD操作方法放到最后,是因为它返回的是数组结果集 ,结果集无法调用辅助方法。所以CURD操作必须放到最后
注意:开发过程里都会遵循使用连贯操作的形式来替代单个辅助方法的写法,优点可读性高
【五】Tp中的统计查询
ThinkPHP中系统封装了以下几个查询方法的使用,方便后期统计的使用。以下几个查询方法在父类模型中不存在,都是由魔术方法__call()生成的
包含count(),max(),min(),avg(),sum()
(1)count() 查询表中总的记录数(有where时表示查询指定条件的记录数)
(2)max() 查询某个字段的最大值
(3)min() 查询某个字段的最小值
(4)avg() 查询某个字段的平均值
(5)sum() 查询某个字段的总和
下面依次介绍
(1)count()
语法:$model -> [where() ->]count; where可选
public function test(){
//实例化模型
$model = M('dept');
$count = $model->count();
dump($count);//返回字符形式的记录总数
}
跟踪信息的sql语句:SELECT COUNT(*) AS tp_count FROM `sp_dept` LIMIT 1 [ RunTime:0.0010s ]
(2)max()
语法:$model->max('字段名');查询指定字段名的最大值
注意:开发中常用来查找最后一个会员注册id
案例:
public function test(){
//实例化模型
$model = M('dept');
$count = $model->max('id');
dump($count);//返回字符形式
}
跟踪信息SQL:SELECT MAX(id) AS tp_max FROM `sp_dept` LIMIT 1 [ RunTime:0.0010s ]
(3)min()
语法:$model->min('字段名'); 指定字段的最小值
注意:实际开发里常用来查询最早注册的会员id
案例:
public function test(){
//实例化模型
$model = M('dept');
$count = $model->min('id');
dump($count);//返回字符形式字符值
}
跟踪信息SQL值:SELECT MIN(id) AS tp_min FROM `sp_dept` LIMIT 1 [ RunTime:0.0000s ]
(4)avg()
语法:$model -> avg('字段名'); 查询字段平均值
public function test(){
//实例化模型
$model = M('dept');
$count = $model->avg('id');
dump($count);//返回字符形式,并保留4位小数
}
跟踪信息SQL:SELECT AVG(id) AS tp_avg FROM `sp_dept` LIMIT 1 [ RunTime:0.0000s ]
(5)sum
语法:$model -> sum('字段名'); 查询某个字段的总和
public function test(){
//实例化模型
$model = M('dept');
$count = $model->sum('id');
dump($count);//返回字符形式字段总和
}
跟踪信息SQL:SELECT SUM(id) AS tp_sum FROM `sp_dept` LIMIT 1 [ RunTime:0.0000s ]
【六】拓展:fetchSql
之前介绍了sql调试的方法getLastSql(别名_sql),但是该方法要求最后一条成功执行的sql,如果拿着个方法来调试sql,只能调试逻辑错误,不能调试语法错误。
所以出现了建立在连贯操作上的fetchSql方法
语法:$model ->where() -> limit() -> order() -> fetchSql(true) -> CURD操作
位置:fetchSql()可以看做是一个辅助方法,所以可以放到模型后,CURD操作之前任意位置。
例如:$model->where()->limit()->order()->fetchSql(true)->CURD操作
版本要求:必须是3.2.3版本之后才可以用
与getLastSql区别:返回值不同,且不会执行sql语句,只会返回sql语句。而getLastSql会返回并执行sql语句
public function test(){
//实例化模型
$model = M('dept');
$count = $model->field('name,count(*) as count') ->group('name')->fetchSql(true)->select();
dump($count);//返回sql语句SELECT `name`,count(*) as count FROM `sp_dept` GROUP BY name
}
跟踪信息SQL没有显示,说明没有被执行,只是被返回(因为没有被执行,所以即使语法错误也不会执行,都将会返回sql语句)。
ThinkPHP---辅助方法的更多相关文章
- thinkphp辅助方法,数据库操作
- MVC学习系列4--@helper辅助方法和用户自定义HTML方法
在HTML Helper,帮助类的帮助下,我们可以动态的创建HTML控件.HTML帮助类是在视图中,用来呈现HTML内容的.HTML帮助类是一个方法,它返回的是string类型的值. HTML帮助类, ...
- 《ASP.NET MVC高级编程(4版)》读书笔记(5)表单和HTML辅助方法
5.1 表单使用 5.1.1 action 和 method 特性 <form action="/Home/Index"> <input name=&qu ...
- MVC辅助方法
我相信很多人虽然经常用mvc去做一些东西,但是可能很少使用mvcHtml辅助方法 首先我们要创建一个mvc项目 二创建一个HtmlHelper文件夹 三编写文件 四调用辅助方法 调用辅助方法 和使用其 ...
- ASP.NET 中HTML和Form辅助方法
Form辅助方法 Form最重要的属性就是action和method,action指明form中的数据被提交到哪里,method指明用什么方法,默认为GET,下面是一个简单的例子: <form ...
- MVC之路随记3--Html辅助方法
概述:MVC中使用@Html.MethodName 来做很多Html的事情,简化了开发工程量,使用方便,并且易于理解 详细方法: 1.表单 <form action="/Home/Se ...
- 表单和 HTML 辅助方法– ASP.NET MVC 4 系列
这里有一个疑问,诸如在文本编辑器中输入 HTML 元素如此简单的任务,也需要任何帮助吗?的确,输入标签名称是很容易的事,但是确保 HTML 页面链接中的 URL 指向正确的位置.表单元素 ...
- MVC中使用内建的HTML辅助方法产生表单元素提交表单与button按钮事件的陷阱
网站模板页有个登陆的退出按钮,当点击时跳转到登陆页面. <button onclick="logout()" >退出</button> $("#l ...
- MVC4.0 扩展辅助方法
新年第一天上班,写个博客开头吧! 在MVC中,辅助类是很常见的,比如说,Html.TextBox().Html.DropDownListFor()等,这些都是微软帮我们封装好的,可以直接调用的,它们解 ...
- Linux共享库 socket辅助方法
//sockhelp.h#ifndef _vx #define _vx #ifdef __cplusplus extern "C" { #endif /** * readn - 读 ...
随机推荐
- uva 10452 Marcus
Problem I Marcus, help! Input: standard input Output: standard output Time Limit: 2 Seconds "Fi ...
- JAVA 并发编程-读写锁之模拟缓存系统(十一)
在多线程中,为了提高效率有些共享资源同意同一时候进行多个读的操作,但仅仅同意一个写的操作,比方一个文件,仅仅要其内容不变能够让多个线程同一时候读,不必做排他的锁定,排他的锁定仅仅有在写的时候须要,以保 ...
- Bootstrap 模态窗口源码分析
前言: bootstrap的 js插件的源码写的非常好,也算是编写jquery插件的模范写法,本来还想大篇详细的分析一下呢,唉,没时间啊,很早之前看过的源码了,现在贴在了博客上, 300来行的代码,其 ...
- spring boot-启动及配置文件
spring boot启动: 1:默认启动方法 public static void main(String[] args) { SpringApplication.run(UserServiceAp ...
- centos ifconfig 无法使用问题
centos ifconfig 无法使用问题 # ifconfig bash: ifconfig: command not found # yum search ifconfig Loaded plu ...
- iOS方法重写
在O-C中子类可以继承父类的方法 ,而不需要从新编写相同的方法,但是有有时候子类并不想原封不动的继承父类的方法,而且是想做一些修改,这就采用啦方法的重写,方法从写有叫做方法覆盖,若子类的中的方法与父类 ...
- java多线程面试题(来自转载)
在典型的Java面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程, 如何创建线程,用什么方式创建线程比较好(比如:继承thread类还是调用Runnable接口),然后逐渐问到并发问 ...
- jQuery.uploadify文件上传组件实例讲解
1.jquery.uploadify简介 在ASP.NET中上传的控件有很多,比如.NET自带的FileUpload,以及SWFUpload,Uploadify等等,尤其后面两个控件的用户体验比较好, ...
- 洛谷P3216 [HNOI2011]数学作业
题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M,要求计算 Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...
- bzoj2115 [Wc2011] Xor——高斯消元 & 异或线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法, ...