前言[随时更新]
MySQL快速复习
MySQL原生查询
选择数据表
删除数据
聚合查询
时间查询
视图查询
子查询
总结/参考
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%', '%COMMENT%', '%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;
}
- 参数为数组,可以为空,即可不传入任何参数;
- 返回是一个由各个条件组合而成的,完整的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赋值的。
还记得SELECT语句最简单的形式吗?我们从此入手:
select方法返回一个结果集,以二维数据表示;
- select方法是我们操作数据库时最重要的一方法
- 该方法不是连贯操作(链式方法),在3.2.3中叫终级方法;
- 该方法定义在SQL生成器类中,一定要注意与普通连贯方法的区别;
- 该方法最典型的用法,就是放在所有连贯操作最后,用来生成SQL语句。
静态调用:用Db类静态方法实现
Db::table(完整表名)->field(字段列表)->select(查询条件); //如定义了表前缀,可用name方法 Db::name(去前缀表名)->field(字段列表)->select(查询条件);
db(去前缀表名)field(字段列表)->select(查询条件);
| 序号 | 参数类型 | 说明 |
|---|---|---|
| 1 | 字符串 | 这是最常用的,简单,直观 |
| 2 | 数组 | 推荐使用,严谨规范,扩展性强 |
| 3 | 布尔 | false:不执行查询,仅返回SQL语句,无true值 |
| 3 | 闭包 | 即匿名函数,可支持更多的查询方法 |
特别提示: 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)
}
}
如果根据主键同时查询多条记录,可将多个主键写在一个字符串。
下面我们将代码中查询语句修改一下:
//查询条件为多个主键组成的字符串:
dump(Db::table('tp5_staff')->field('id,name,salary')->select('1006,1008,1010'));
这时,应该返回主键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)
}
}
<?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)
}
}
同字符串做参数类似,多个主键查询时,只需要把多个主键值做为数组元素即可
我们改写一下上面代码中关键语句:
//查询条件为多个主键字符串组成的索引数组:
dump(Db::table('tp5_staff')->field('id,name,salary')->select(['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)
}
}
采用数组做为参数,可以构造更为复杂的查询条件,下面我们演示一下,在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']]));
}
}
有的同学,看到这里,可能有点发懵,这不是多此一举吗?明明一个字符串就可以解决的事,干吗整得这么复杂?那么问题来了:
1、如果要查询id大于1010的员工信息,怎么办?
2、如果要查询id号位于1010到1015之间的员工信息怎么办?
显然,字符串仅提供了简单的相等查询,更为复杂的查询,就无能为力了。
明白上以上内容,现在就简单多了,只需要把比较运算符由“=”,换成“>”就行了
<?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)
}
}
1.只能填false,不能填:true
2.false:不执行查询,返回查询SQL语句
<?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
1、补充知识:闭包就是匿名函数,所谓匿名,就是没有名字。
2、我们知道,变量或函数,都是按名调用,没有名称,如何调用呢?
3、匿名并不是没有名字,而是指名字不固定,是一个可随意变化的值;
4、匿名函数,一句话概括:就是用变量名来调用的函数。
<?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');
}));
}
}
$query->table('tp5_staff')->field('id,name,salary')->where('salary >= 5000');
1、select方法,除闭包外,不推荐使用参数;
2、所有查询条件,应该在前面用链式操作构成~~