http://doc.thinkphp.cn/manual/query.html
SQL查询
ThinkPHP内置的ORM和ActiveRecord模式实现了方便的数据存取操作,而且新版增加的连贯操作功能更是让这个数据操作更加清晰,但是ThinkPHP仍然保留了原生的SQL查询和执行操作支持,为了满足复杂查询的需要和一些特殊的数据操作,SQL查询的返回值因为是直接返回的Db类的查询结果,没有做任何的处理。主要包括下面两个方法:
1、query方法
query 执行SQL查询操作 | |
---|---|
用法 | query($sql,$parse=false) |
参数 | query(必须):要查询的SQL语句 parse(可选):是否需要解析SQL |
返回值 |
如果数据非法或者查询错误则返回false 否则返回查询结果数据集(同select方法) |
使用示例:
- $Model = new Model() // 实例化一个model对象 没有对应任何数据表
- $Model->query("select * from think_user where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的SQL语句是什么。
2、execute方法
execute用于更新和写入数据的sql操作 | |
---|---|
用法 | execute($sql,$parse=false) |
参数 | query(必须):要执行的SQL语句 parse(可选):是否需要解析SQL |
返回值 | 如果数据非法或者查询错误则返回false 否则返回影响的记录数 |
使用示例:
- $Model = new Model() // 实例化一个model对象 没有对应任何数据表
- $Model->execute("update think_user set name=‘thinkPHP‘ where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。
3、其他技巧
自动获取当前表名
通常使用原生SQL需要手动加上当前要查询的表名,如果你的表名以后会变化的话,那么就需要修改每个原生SQL查询的sql语句了,针对这个情况,系统还提供了一个小的技巧来帮助解决这个问题。
例如:
- $model = M("User");
- $model->query(‘select * from __TABLE__ where status>1‘);
我们这里使用了__TABLE__ 这样一个字符串,系统在解析的时候会自动替换成当前模型对应的表名,这样就可以做到即使模型对应的表名有所变化,仍然不用修改原生的sql语句。
支持连贯操作和SQL解析
新版对query和execute两个原生SQL操作方法增加第二个参数支持, 表示是否需要解析SQL (默认为false 表示直接执行sql ),如果设为true 则会解析SQL中的特殊字符串 (需要配合连贯操作)。
例如,支持 如下写法:
- $model->table("think_user")
- ->where(array("name"=>"thinkphp"))
- ->field("id,name,email")
- ->query(‘select %FIELD% from %TABLE% %WHERE%‘,true);
其中query方法中的%FIELD%、%TABLE%和%WHERE%字符串会自动替换为同名的连贯操作方法的解析结果SQL,支持的替换字符串包括:
替换字符串 | 对应连贯操作方法 |
---|---|
%FIELD% | field |
%TABLE% | table |
%DISTINCT% | distinct |
%WHERE% | where |
%JOIN% | join |
%GROUP% | group |
%HAVING% | having |
%ORDER% | order |
%LIMIT% | limit |
%UNION% | union |
3
动态查询
借助PHP5语言的特性,ThinkPHP实现了动态查询,包括下面几种:
方法名 | 说明 | 举例 |
---|---|---|
getBy | 根据某个字段的值查询数据 | 例如,getByName,getByEmail |
getFieldBy | 根据某个字段查询并返回某个字段的值 | 例如,getFieldByName |
top | 获取前多少条记录(需要高级模型支持) | 例如,top8,top12 |
一、getBy动态查询
该查询方式针对数据表的字段进行查询。例如,User对象拥有id,name,email,address 等属性,那么我们就可以使用下面的查询方法来直接根据某个属性来查询符合条件的记录。
- $user = $User->getByName(‘liu21st‘);
- $user = $User->getByEmail(‘[email protected]‘);
- $user = $User->getByAddress(‘中国深圳‘);
暂时不支持多数据字段的动态查询方法,请使用find方法和select方法进行查询。
二、getFieldBy动态查询
针对某个字段查询并返回某个字段的值,例如
- $user = $User->getFieldByName(‘liu21st‘,‘id‘);
表示根据用户的name获取用户的id值。
三、top动态查询
ThinkPHP还提供了另外一种动态查询方式,就是获取符合条件的前N条记录(和定位查询一样,也要求当前模型类必须继承高级模型类后才能使用)。例如,我们需要获取当前用户中积分大于0,积分最高的前5位用户 :
- $User-> where(‘score>80‘)->order(‘score desc‘)->top5();
要获取积分的前8位可以改成:
- $User-> where(‘score>80‘)->order(‘score desc‘)->top8();
5
子查询
新版新增了子查询支持,有两种使用方式:
1、使用select方法
当select方法的参数为false的时候,表示不进行查询只是返回构建SQL,例如:
- // 首先构造子查询SQL
- $subQuery = $model->field(‘id,name‘)->table(‘tablename‘)->group(‘field‘)->where($where)->order(‘status‘)->select(false);
2、使用buildSql方法
- $subQuery = $model->field(‘id,name‘)->table(‘tablename‘)->group(‘field‘)->where($where)->order(‘status‘)->buildSql();
调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号),然后我们直接在后续的查询中直接调用。
- // 利用子查询进行查询
- $model->table($subQuery.‘ a‘)->where()->order()->select()
构造的子查询SQL可用于TP的连贯操作方法,例如table where等。
SQL查询 thinkphp