第 39 章 ThinkPHP--SQL 连贯操作
本节课,我们将学习 ThinkPHP 模型基础类提供的连贯操作,通过连贯操作可以有效的 提供数据存取的代码清晰度和开发效率,并且支持所有的 CURD 操作。
一.连贯入门 连贯操作使用起来非常简单,比如查找到 id 为 1,2,3,4 中按照创建时间的倒序的前两 位。
//连贯操作入门 $user = M('User'); var_dump($user->where('id in (1,2,3,4)')->order('date DESC')->limit(2)->select());
PS:这里的 where、order 和 limit 方法都是连贯操作方法,所以它们都能返回$user 本身,可以互换位置。
而 select 方法不是连贯方法,需要放在最后,用以显示数据集。
//数组操作 $user = M('User'); var_dump($user->select(array('where'=>'id in (1,2,3,4)', 'limit'=>'2', 'order'=>'date DESC')));
//CURD处理,CURD会在专门章节讲解
$user = M('User'); var_dump($user->where('id=1')->find()); var_dump($user->where('id=7')->delete());
系统支持的连贯方法 连贯操作 作用 支持的参数类型
where* 用于查询或者更新条件的定义 字符串、数组和对象
table 用于定义要操作的数据表名称字符串和数组
alias 用于给当前数据表定义别名 字符串
data 用于新增或者更新数据之前的数据对 象赋值 数组和对象
field 用于定义要查询的字段(支持字段排 除) 字符串和数组
order 用于对结果排序 字符串和数组
limit 用于限制查询结果数量 字符串和数字
page 用于查询分页(内部会转换成 limit) 字符串和数字
group 用于对查询的 group 支持 字符串
having 用于对查询的 having 支持 字符串
join* 用于对查询的 join 支持 字符串和数组
union* 用于对查询的 union 支持 字符串、数组和对象
distinct 用于查询的 distinct 支持 布尔值
lock 用于数据库的锁机制 布尔值
cache 用于查询缓存 支持多个参数
relation 用于关联查询(需要关联模型支持) 字符串
result 用于返回数据转换 字符串
validate 用于数据自动验证 数组
auto 用于数据自动完成 数组
filter 用于数据过滤 字符串 scope* 用于命名范围 字符串、数组 bind* 用于数据绑定操作 数组或多个参数 token 用于令牌验证 布尔值 comment 用于 SQL 注释 字符串
PS:带*号的可以多次调用。
本节课没有讲到的连贯方法,会在其他章节探讨。
二.连贯方法
1.where where 方法支持字符串条件、数组条件(推荐用法)和多次调用。
//字符串方式 $user = M('User'); var_dump($user->where('id=1')->select()); //索引数组方式 $user = M('User'); $map['id'] = 1; //使用表达式array('eq', 1); var_dump($user->where($map)->select()); //多次调用方式 $user = M('User'); $map['id'] = array('eq', 1); var_dump($user->where($map)->where('user="蜡笔小新"')->select());
2.order order 用于对结果集排序。
//倒序 $user = M('User'); $map['id'] = array('eq', 1); var_dump($user->order('id desc')->select()); //正序默认或 ASC //第二排序 var_dump($user->order('id desc,email desc')->select());
PS:先按 id 倒序,再按 email 倒序 //数组形式防止字段和mysql关键字冲突
$user = M('User'); $map['id'] = array('eq', 1); var_dump($user->order(array('id'=>'DESC'))->select());
3.feild feild 方法可以返回或操作字段,可以用于查询和写入操作。
//只显示id和user两个字段 $user = M('User'); var_dump($user->field('id, user')->select()); //使用SQL函数和别名 $user = M('User'); var_dump($user->field('SUM(id) as count, user')->select()); //使用数组参数结合SQL函数 $user = M('User'); var_dump($user->field(array('id','LEFT(user,3)'=>'left_user'))->sele ct()); //获取所有字段 $user = M('User'); var_dump($user->field()->select()); //可以传入*号,或者省略方法 //用于写入 $user = M('User'); $user->field('user,email')->create();
//CURD 将在专门的章节学习
3.limit limit 方法主要用于指定查询和操作的数量。
//限制结果集数量 $user = M('User'); var_dump($user->limit(2)->select());
//分页查询 $user = M('User'); var_dump($user->limit(0,2)->select());
limit(0,2)中0表示从第几个开始,2表示每页显示条数。建议采用更为方便的page分页方法
//2,2、,4,2
4.page page 方法完全用于分页查询。
//page分页 $user = M('User');
var_dump($user->page(1,2)->select());
page方法非常方便,page(1,2)中,1代表第一页,2代表每页显示条数。
//2,2、3,2
5.table table 方法用于数据表操作,主要是切换数据表或多表操作。
//切换数据表 $user = M('User'); var_dump($user->table('think_info')->select()); //获取简化表名 $user = M('User'); var_dump($user->table('__USER__')->select());
注:若使用简化表名 要用大写,小写则无法执行;
//__INFO__尚可 //多表查询 $user = M('User'); var_dump($user->field('a.id,b.id')->table('__USER__ a,__INFO__ b')->select());
//多表查询,使用数组形式避免关键字冲突
$user = M('User'); var_dump($user->field('a.id,b.id')->table(array('think_user'=>'a', 'think_info'=>'b'))->select());
6.alias alias 用于设置数据表别名
//设置别名 $user = M('User'); var_dump($user->alias('a')->select());
7.group group 方法通常用于对结合函数统计的结果集分组。
//分组统计 $user = M('User'); var_dump($user->field('user,max(id)')->group('id')->select());
PS:group 会在 mysql 部分单独探讨。
8.having having 方法一般用于配合 group 方法完成从分组的结果中再筛选数据。
//分组统计结合having $user = M('User'); var_dump($user->field('user,max(id)')->group('id')->having('id>2')-> select());
PS:having 会在 mysql 部分单独探讨。
9.comment comment 方法用于对 SQL 语句进行注释
//SQL注释 $user = M('User'); var_dump($user->comment('所有用户')->select());
10.join join 方法用于多表的连接查询。
//JOIN多表关联,默认是INNER JOIN $user = M('User'); var_dump($user->join('think_user ON think_info.id = think_user.id')->select()); //__USER__和__INFO__代替 //RIGHT、LEFT、FULL var_dump($user->join('think_user ON think_info.id = think_user.id','RIGHT')->select());
PS:join 会在 mysql 部分单独探讨。
11.union union 方法用于合并多个 SELECT 的结果集
//合并多个SELECT结果集 $user = M('User'); var_dump($user->union("SELECT * FROM think_info")->select());
PS:union 会在 mysql 部分单独探讨。
12.distinct distinct 方法用于返回唯一不同的值
//返回不重复的列 $user = M('User'); var_dump($user->distinct(true)->field('user')->select());
13.cache cache 用于查询缓存操作
//查询缓存,第二次读取缓存内容 $user = M('User'); var_dump($user->cache(true)->select());
PS:第一次查询数据库,第二次查询相同的内容直接调用缓存,不用再查询数据库。
更多关于 cache 和缓存的使用方法,我们将在缓存那节详细探讨。
三.命名范围 命名范围其实就是将 SQL 语句封装在模型定义类里,而不在控制器里。
这样的分层操 作有利于代码的可读性,避免开发人员在写 CURD 操作时出现问题。
架构人员只要在命名范 围内合理的规划即可,类似于架构师架构了接口,让开发人员面向接口开发一样。
要使用命名范围,第一步要定义属性:
class UserModel extends Model { protected $_scope = array( //属性名必须是_scope 'sql1'=>array( 'where'=>array('id'=>1), ), 'sql2'=>array( 'order'=>'date DESC', 'limit'=>2, ), 'default'=>array( 'where'=>array('id'=>2), ), ); } 命名范围支持的属性有:where、field、order、table、limit、page、having、 group、lock、distinct、cache。
//调用命名范围 $user = D('User'); var_dump($user->scope('sql2')->select()); //支持调用多个scope方法 $user = D('User'); var_dump($user->scope('sql1')->scope('sql2')->select()); //default默认 $user = D('User'); var_dump($user->scope()->select()); //传递 default 也行 PS:如果传递不存在的命名范围,则忽略。 //对命名范围的SQL进行调整 $user = D('User'); var_dump($user->scope('sql2', array('limit'=>4))->select()); //直接覆盖命名范围 $user = D('User'); var_dump($user->scope(array('where'=>1,'order'=>'date DESC','limit'=>2))->select()); //直接用命名范围名调用 $user = D('User'); var_dump($user->sql2()->select());