[TOC]
## select方法的使用
#### 1、 功能:根据查询器条件,生在查询SQL语句
#### 2、源码位置:/thinkphp/library/think/db/Builder.php
>[success] 1、其实在Query.php查询类中也有一个select方法,使用是产生子查询;
2、该方法要产生查询结果,本质还是调用SQL生成器类Builder.php中select方法;
3、该类不是我们教学内容,等用到时再详细说明,本处不做过多介绍。
~~~
/**
* 生成查询SQL
* @access public
* @param array $options 表达式
* @return string
*/
public function select($options = [])
{
$sql = str_replace(
['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '', '%FORCE%'],
[
$this->parseTable($options['table'], $options),
$this->parseDistinct($options['distinct']),
$this->parseField($options['field'], $options),
$this->parseJoin($options['join'], $options),
$this->parseWhere($options['where'], $options),
$this->parseGroup($options['group']),
$this->parseHaving($options['having']),
$this->parseOrder($options['order'], $options),
$this->parseLimit($options['limit']),
$this->parseUnion($options['union']),
$this->parseLock($options['lock']),
$this->parseComment($options['comment']),
$this->parseForce($options['force']),
], $this->selectSql);
return $sql;
}
~~~
* 源码分析:
>[info] * 参数为数组,可以为空,即可不传入任何参数;
* 返回是一个由各个条件组合而成的,完整的SELECT查询语句字符串;
* 内部是通过一个str_replace()字符串替换函数实现,该函数有二个参数,均是数组形式;
* 从字符替换函数第二个参数可以看出该select方法支持的连贯方法有哪些?
* 方法有下面这些:
`tabble,distinct,field,join,where,group,having,order,limit,union,lock,comment,force`等,这些方法,后面我们都将一一讲到。
* 在源码中,没有列出的连贯方法,就是不支持的方法,在select方法之前不要使用;
* 这些方法,全部会拼接成查询选项,最终放在Query类的静态options属性数组中。
* Query 类中,有并查询要用的属性如下:
~~~
class Query
{
// 数据库Connection对象实例
protected $connection;
// 数据库驱动类型
protected $builder;
// 当前模型类名称
protected $model;
// 当前数据表名称(含前缀)
protected $table = '';
// 当前数据表名称(不含前缀)
protected $name = '';
// 当前数据表主键
protected $pk;
// 当前数据表前缀
protected $prefix = '';
// 查询参数
protected $options = [];
// 参数绑定
protected $bind = [];
// 数据表信息
protected static $info = [];
~~~
* 是不是很眼熟呢?对,我们之前学习过table和name方法,就是完成给静态属性$table和$name赋值的。
#### 3、参数和返回值
* 还记得SELECT语句最简单的形式吗?我们从此入手:
* <font color="forestgreen">SELECT 字段列表 FROM 表名 WHERE 查询条件</font>
* 字段列表由:field方法提供;
* 数据表由:table方法、name方法或者db助手函数提供;
* select 可接受Query类中$options查询参数属性做为参数;
* 更多情况,查询条件由select之前的查询器方法提供;
* select方法的参数推荐不填写,全部由前面查询器提供。
* select方法返回一个结果集,以二维数据表示;
#### 4、适用环境或条件
>[success] * select方法是我们操作数据库时最重要的一方法
> * 该方法不是连贯操作(链式方法),在3.2.3中叫终级方法;
> * 该方法定义在SQL生成器类中,一定要注意与普通连贯方法的区别;
> * 该方法最典型的用法,就是放在所有连贯操作最后,用来生成SQL语句。
#### 5、调用语法:
* 静态调用:用Db类静态方法实现
~~~
Db::table(完整表名)->field(字段列表)->select(查询条件);
//如定义了表前缀,可用name方法
Db::name(去前缀表名)->field(字段列表)->select(查询条件);
~~~
* 动态调用:用助手函数db实现
~~~
db(去前缀表名)field(字段列表)->select(查询条件);
~~~
* 参数部分,如表名、字段列表、查询条件可以使用以下类型:
| 序号 | 参数类型 | 说明 |
| --- | --- | --- |
| 1 | 字符串 | 这是最常用的,简单,直观 |
| 2 | 数组 | 推荐使用,严谨规范,扩展性强 |
| 3 | 布尔 | false:不执行查询,仅返回SQL语句,无true值|
| 3 | 闭包 | 即匿名函数,可支持更多的查询方法 |
#### 6、实例:查询id=1006的员工姓名和工资
> <font color="DeepPink">特别提示:</font> select参数仅限主键查询
目前表中数据如下:
![](https://box.kancloud.cn/d7c5b8f8b5633d449b16611dc10e435e_612x280.png)
#### 1.字符串做select参数
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
//查询条件为字符串:
dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006'));
}
}
~~~
查询结果如下:
~~~
array(1) {
[0] => array(3) {
["id"] => int(1006)
["name"] => string(9) "西门庆"
["salary"] => float(19801)
}
}
~~~
>[info] 如果根据主键同时查询多条记录,可将多个主键写在一个字符串。
下面我们将代码中查询语句修改一下:
~~~
//查询条件为多个主键组成的字符串:
dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006,1008,1010'));
~~~
>[success]这时,应该返回主键id为1006、1008和1010三条记录
~~~
array(3) {
[0] => array(3) {
["id"] => int(1006)
["name"] => string(9) "西门庆"
["salary"] => float(19801)
}
[1] => array(3) {
["id"] => int(1008)
["name"] => string(6) "宋江"
["salary"] => float(9261)
}
[2] => array(3) {
["id"] => int(1010)
["name"] => string(9) "欧阳峰"
["salary"] => float(4900)
}
}
~~~
#### 2. 数组做select参数
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
//查询条件为字符串:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['1006']));
}
}
~~~
>[success] 可以看出,与字符串做参数相比,区别仅仅是把主键字符串做为元素,放在了索引数组中
查询结果如下:
~~~
array(1) {
[0] => array(3) {
["id"] => int(1006)
["name"] => string(9) "西门庆"
["salary"] => float(19801)
}
}
~~~
>[success] 同字符串做参数类似,多个主键查询时,只需要把多个主键值做为数组元素即可
我们改写一下上面代码中关键语句:
~~~
//查询条件为多个主键字符串组成的索引数组:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['1006','1008','1010']));
~~~
>[success] 返回的查询结果与上面是一样的:
~~~
array(3) {
[0] => array(3) {
["id"] => int(1006)
["name"] => string(9) "西门庆"
["salary"] => float(19801)
}
[1] => array(3) {
["id"] => int(1008)
["name"] => string(6) "宋江"
["salary"] => float(9261)
}
[2] => array(3) {
["id"] => int(1010)
["name"] => string(9) "欧阳峰"
["salary"] => float(4900)
}
}
~~~
>[success] 采用数组做为参数,可以构造更为复杂的查询条件,下面我们演示一下,在select方法中,用关联数组,构造更为复杂些查询表达式。
* 我们做关联数组方式,将上面的例子再次改写一下
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
//查询条件关联数组,键名为表主键,后面紧跟着给出条件:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['id'=>['=','1010']]));
}
}
~~~
>[info] 有的同学,看到这里,可能有点发懵,这不是多此一举吗?明明一个字符串就可以解决的事,干吗整得这么复杂?那么问题来了:
1、如果要查询id大于1010的员工信息,怎么办?
2、如果要查询id号位于1010到1015之间的员工信息怎么办?
显然,字符串仅提供了简单的相等查询,更为复杂的查询,就无能为力了。
* 实例:查询id大于1010的员工信息
>明白上以上内容,现在就简单多了,只需要把比较运算符由“=”,换成“>”就行了
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
//查询条件关联数组,键名为表主键,后面紧跟着给出条件:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['id'=>['>','1010']]));
}
}
~~~
* 查询结果如下:
~~~
array(2) {
[0] => array(3) {
["id"] => int(1011)
["name"] => string(9) "李云龙"
["salary"] => float(4800)
}
[1] => array(3) {
["id"] => int(1012)
["name"] => string(9) "楚云飞"
["salary"] => float(4800)
}
}
~~~
#### 3、布尔值做select参数
>[warning] 1.只能填false,不能填:true
2.false:不执行查询,返回查询SQL语句
* Index.php :
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
// 1.获取工资大于5000的员工信息
$result = Db::table('tp5_staff') //指定tp5_staff表
->field(['id'=>'编号','name'=>'姓名','salary'=>'工资']) //设置返回字段
->where('salary','>',5000) //设置查询条件
->select(false); // 生成SQL语句字符串
// 2、输出查询SQL字符串
echo $result;
}
}
~~~
* 运行结果:
~~~
SELECT `id` AS `编号`,`name` AS `姓名`,`salary` AS `工资` FROM `tp5_staff` WHERE `salary` > 5000
~~~
#### 4. 闭包做select参数
>[info] 1、补充知识:闭包就是匿名函数,所谓匿名,就是没有名字。
2、我们知道,变量或函数,都是按名调用,没有名称,如何调用呢?
3、匿名并不是没有名字,而是指名字不固定,是一个可随意变化的值;
4、匿名函数,一句话概括:就是用变量名来调用的函数。
* 实例:查询工资大于5000无的员工基本信息
~~~
<?php
namespace app\index\controller;
use think\Db;
class Index {
public function index(){
//闭包参数支持更多的查询方法,可以构造更加复杂的查询器
dump(Db::select(function ($query){
$query->table('tp5_staff')->field('id,name,salary')->where('salary >= 5000');
}));
}
}
~~~
* 代码中的闭包函数部分,将select方法之前的所有查询器方法全部集成到了闭包中:
~~~
$query->table('tp5_staff')->field('id,name,salary')->where('salary >= 5000');
~~~
* ThinkPHP 5 中大量的应用到了闭包查询,从现在起,同学们一定要适应这种变化
* * * * *
### 总结:
>[success]1、select方法,除闭包外,不推荐使用参数;
2、所有查询条件,应该在前面用链式操作构成~~</font>
- 前言[随时更新]
- ThinkPHP 5数据库重构
- 开发环境
- 1.ThinkPHP5开发环境(Mac版)
- 2.ThinkPHP5开发环境(Win版)
- MySQL快速复习
- 1.数据库操作
- 2.数据表操作
- 1.创建数据表 (重点)
- 2.添加数据表记录
- 3.查询数据表(重点)
- 4.更新数据表
- 5.编辑数据表结构(重点)
- 6_复制数据表
- 7.删除数据和表
- 连接数据库
- 1.数据库配置文件database.php
- 2.Db类静态方法connect()
- 3.模块中的配置文件config.php
- MySQL原生查询
- 1.读操作query
- 2.写操作execute
- 选择数据表
- 1.table与setTable方法
- 2.name方法
- 3.db助手函数
- 4.alias方法
- 结果集查询
- 1.find方法
- 2.select方法
- 3.fetchSql方法
- 4.value方法
- 5.column方法
- 6.field方法
- 新增数据
- 1.insert_单条添加
- 2.insertAll_批量添加
- 3_db_助手函数添加
- 更新数据
- 1.update方法
- 2.setField更新字段
- 3_自增自减与延时更新
- 删除数据
- 1.delete方法
- 查询方法
- 1.getTableInfo方法
- 2.where方法
- 3.whereOr方法
- 4.混合查询(闭包实现)
- 表达式查询
- 1.表达式查询(重点)
- 2.exp通用查询
- 分组查询
- 1.group方法
- 2.having方法
- 排序分页查询
- 1.order方法
- 2.limit方法
- 3.page方法
- 聚合查询
- 时间查询
- 1.where方法
- 2.whereTime方法
- 高级查询
- 1.快捷查询
- 2.区间查询
- 3.批量查询
- 4.Query对象查询
- 5.混合查询
- 视图查询
- view方法
- 子查询
- 1.select方法
- 2.fetchSql方法
- 3.buildSql方法
- 4.闭包子查询
- 总结/参考
- 1.方法参数类型总结
- 2.查询/子查询/连接查询