ThinkPHP模型基础类提供的连贯操作方法(也有些框架称之为链式操作),可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的CURD操作。
使用也比较简单, 假如我们现在要查询一个User表的满足状态为1的前10条记录,并希望按照用户的创建时间排序 ,代码如下:
$User->where('status=1')->order('create_time')->limit(10)->select();
这里的where
、order
和limit
方法就被称之为连贯操作方法,除了select方法必须放到最后一个外(因为select方法并不是连贯操作方法),连贯操作的方法调用顺序没有先后。
常用操作:
//造模型对象 $nation = D("Nation"); //查询 //$a = $nation->select(); //查所有,返回关联数组 //$a = $nation->select("n001,n002,n003"); //通过主键查 //$a = $nation->find("n002"); //查一条数据 //$a = $nation->table("Info")->select(); //切换表 //$a = $nation->field("name")->select(); //查询指定字段 另: //$sql = "update nation set name='矮人族' where code='n001'"; //$a = $nation->query($sql); //执行查询 //$a = $nation->execute($sql); //执行其他操作
ALIAS操作:
alias用于设置当前数据表的别名,便于使用其他的连贯操作例如join方法等。
$Model = M('User'); $Model->alias('a')->join('__DEPT__ b ON b.user_id= a.id')->select();
最终生成的sql语句类似于:
SELECT * FROM think_user a INNER JOIN think_dept b ON b.user_id= a.id
$a = $nation->alias('a')->field("b.Code as 'code',b.Name as 'name',a.name as '民族'")->join("Info b on a.Code=b.Nation")->select();
ORDER操作:
$a = $nation->order("code desc")->select(); //排序
支持对多个字段的排序,例如:
$Model->where('status=1')->order('id desc,status')->limit(5)->select(); 如果没有指定desc或者asc排序规则的话,默认为asc。
如果你的字段和mysql关键字有冲突,那么建议采用数组方式调用,例如:
$Model->where('status=1')->order(array('order','id'=>'desc'))->limit(5)->select();
LIMIT操作和PAGE操作:
$a = $nation->limit(3,3)->select(); //分页 $a = $nation->page(3,3)->select(); //分页
限制结果数量:
例如获取满足要求的10个用户,如下调用即可:
$User = M('User'); $User->where('status=1')->field('id,name')->limit(10)->select();
limit方法也可以用于写操作,例如更新满足要求的3条数据:
$User = M('User'); $User->where('score=100')->limit(3)->save(array('level'=>'A'));
page方法也是模型的连贯操作方法之一,是完全为分页查询而诞生的一个人性化操作方法。
如果使用limit方法,我们要查询第一页和第二页(假设我们每页输出10条数据)写法如下:
$Article = M('Article'); $Article->limit('0,10')->select(); // 查询第一页数据 $Article->limit('10,10')->select(); // 查询第二页数据
如果用page方法来写则简单多了,例如:
$Article = M('Article'); $Article->page(1,10)->select(); // 查询第一页数据 $Article->page(2,10)->select(); // 查询第二页数据
显而易见的是,使用page方法你不需要计算每个分页数据的起始位置,page方法内部会自动计算。
page方法还可以和limit方法配合使用,例如:
$Article->limit(25)->page(3)->select();
GROUP操作和HAVING操作:
$a = $nation->table("Car")->field("Brand,avg(Price)")->group("Brand")->select(); //分组 $a = $nation->table("Car")->field("Brand,avg(Price)")->group("Brand")->having("avg(Price)>50")->select();
group方法只有一个参数,并且只能使用字符串。
也支持对多个字段进行分组,例如:
$this->field('username,max(score)')->group('user_id,test_time')->select();
生成的SQL语句是:
SELECT username,max(score) FROM think_score GROUP BY user_id,test_time
DISTINCT方法:
DISTINCT 方法用于返回唯一不同的值 。
例如:
$Model->distinct(true)->field('name')->select();
生成的SQL语句是: SELECT DISTINCT name FROM think_user
distinct方法的参数是一个布尔值.
JOIN方法:
JOIN方法也是连贯操作方法之一,用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
join通常有下面几种类型,不同类型的join操作会影响返回的数据结果。
- INNER JOIN: 如果表中有至少一个匹配,则返回行,等同于 JOIN
- LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
- RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
- FULL JOIN: 只要其中一个表中存在匹配,就返回行
join方法支持多次调用,但指定的数据表必须是全称,但我们可以这样来定义:
$Model ->join('__WORK__ ON __ARTIST__.id = __WORK__.artist_id') ->join('__CARD__ ON __ARTIST__.card_id = __CARD__.id') ->select();
__WORK__
和 __CARD__
在最终解析的时候会转换为 think_work
和 think_card
。
默认采用INNER JOIN 方式,如果需要用其他的JOIN方式,可以改成
$Model->join('RIGHT JOIN __WORK__ ON __ARTIST__.id = __WORK__.artist_id')->select()
或者使用:
$Model->join('__WORK__ ON __artist__.id = __WORK__.artist_id','RIGHT')->select()
UNION方法:
UNION操作用于合并两个或多个 SELECT 语句的结果集。
$Model->field('name') ->table('think_user_0') ->union('SELECT name FROM think_user_1') ->union('SELECT name FROM think_user_2') ->select();
数组用法:
$Model->field('name') ->table('think_user_0') ->union(array('field'=>'name','table'=>'think_user_1')) ->union(array('field'=>'name','table'=>'think_user_2')) ->select();
或者:
$Model->field('name') ->table('think_user_0') ->union(array('SELECT name FROM think_user_1','SELECT name FROM think_user_2')) ->select();
注意:UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。
COMMENT方法:
COMMENT方法 用于在生成的SQL语句中添加注释内容,例如:
$this->comment('查询考试前十名分数') ->field('username,score') ->limit(10) ->order('score desc') ->select();
最终生成的SQL语句是:
SELECT username,score FROM think_score ORDER BY score desc LIMIT 10 /* 查询考试前十名分数 */
DATA方法:
data方法也是模型类的连贯操作方法之一,用于设置当前要操作的数据对象的值。
写操作:
通常情况下我们都是通过create方法或者赋值的方式生成数据对象,然后写入数据库,例如:
$Model = D('User'); $Model->create(); // 这里略过具体的自动生成和验证判断 $Model->add();
又或者直接对对象赋值,例如:
$Model = M('User'); $Model->name = '流年'; $Model->email = 'thinkphp@qq.com'; $Model->add();
那么data方法则是直接生成要操作的数据对象,例如:
$Model = M('User'); $data['name'] = '流年'; $data['email'] = 'thinkphp@qq.com'; $Model->data($data)->add();
注意:如果我们同时使用create方法和data创建数据对象的话,则最后调用的方法有效。
data方法支持数组、对象和字符串,对象方式如下:
$Model = M('User'); $obj = new stdClass; $obj->name = '流年'; $obj->email = 'thinkphp@qq.com'; $Model->data($obj)->add();
字符串方式用法如下:
$Model = M('User'); $data = 'name=流年&email=thinkphp@qq.com'; $Model->data($data)->add();
也可以直接在add方法中传入数据对象来新增数据,例如:
$Model = M('User'); $data['name'] = '流年'; $data['email'] = 'thinkphp@qq.com'; $Model->add($data);
但是这种方式data参数只能使用数组。
当然data方法也可以用于更新数据,例如:
$Model = M('User'); $data['id'] = 8; $data['name'] = '流年'; $data['email'] = 'thinkphp@qq.com'; $Model->data($data)->save();
当然我们也可以直接这样用:
$Model = M('User'); $data['id'] = 8; $data['name'] = '流年'; $data['email'] = 'thinkphp@qq.com'; $Model->save($data);
同样,此时data参数只能传入数组。
在调用save方法更新数据的时候 会自动判断当前的数据对象里面是否有主键值存在,如果有的话会自动作为更新条件。也就是说,下面的用法和上面等效:
$Model = M('User'); $data['name'] = '流年'; $data['email'] = 'thinkphp@qq.com'; $Model->data($data)->where('id=8')->save();
读操作:
除了写操作外,data方法还可以用于读取当前的数据对象,例如:
$User = M('User'); $map['name'] = '流年'; $User->where($map)->find(); // 读取当前数据对象 $data = $User->data();