view方法
1、功能:视图查询可以实现不依赖数据库视图的多表查询,并不需要数据库支持视图
2、源码:/thinkphp/library/think/db/Query.php/**
* 指定JOIN查询字段
* @access public
* @param string|array $table 数据表
* @param string|array $field 查询字段
* @param string|array $on JOIN条件
* @param string $type JOIN类型
* @return $this
*/
public function view($join, $field = true, $on = null, $type = 'INNER')
{
$this->options['view'] = true;
if (is_array($join) && is_null($field)) {
foreach ($join as $key => $val) {
$this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER');
}
} else {
$fields = [];
$prefix = $this->prefix;
if (is_array($join)) {
// 支持数据表别名
list($table, $alias) = each($join);
} elseif ($prefix && false === strpos($join, ' ') && 0 !== strpos($join, $prefix) && 0 !== strpos($join, '__')) {
$table = $this->getTable($join);
$alias = $join;
} elseif (strpos($join, ' ')) {
list($table, $alias) = explode(' ', $join);
} else {
$alias = $join;
}
$table = isset($table) ? [$table => $alias] : $alias;
if (true === $field) {
$fields = $alias . '.*';
} else {
if (is_string($field)) {
$field = explode(',', $field);
}
foreach ($field as $key => $val) {
if (is_numeric($key)) {
$fields[] = $alias . '.' . $val;
$this->options['map'][$val] = $alias . '.' . $val;
} else {
if (preg_match('/[,=\.\'\"\(\s]/', $key)) {
$name = $key;
} else {
$name = $alias . '.' . $key;
}
$fields[] = $name . ' AS ' . $val;
$this->options['map'][$val] = $name;
}
}
}
$this->field($fields);
if ($on) {
$this->join($table, $on, $type);
} else {
$this->table($table);
}
}
return $this;
}源码简要分析:理解参数的含义是重点;例如$join和$field即可以字符串与可以数组;
连接类型的含义:左连接、右连接、全连接;
PHP原生each和list函数将参数拆分到变量中,实现对表和字段别名的支持。
3、参数与返回值返回值也其它方法一样,返回当前查询对象Query;
参数序号参数说明1$join / 字符串 / 数组$join为字符串是$table表名,数组时解析成表名与表别名
2$field / 字符串 / 数组字符串表示字段列表,数组是包含字段别名
3$on / 字符串 / 数组多表连接条件
4$type / 字符串连接类型,默认为INNER,支持LEFT左连接、RIGHT右连接
4、实例演示:视图查询有很多种写法,很灵活,这里演示一种较为规划的标准格式,用到了前面学过的多种语法:
任务1:查询tp5_staff表tp5_dept表,输出员工编号、姓名、部门名称(中文),并且要求年龄大于50,工资小于等于8000的三名员工,降序输出分析:tp5_staff表中仅存储部门编号id,其部门中文名称存在另一张表:tp5_dept中,因为需要二张表联合查询,因为第1张表可能会有与部门表tp5_dept不对应的部门id,所以采用左连接。为简化操作,直观表达,这里表名与字段名全部采用别名。Index.php 控制器代码如下:<?php
namespace app\index\controller;
//导入数据库类
use think\Db;
class Index {
public function index(){
//1.设置视图查询条件
$table1 = ['tp5_staff'=>'a']; //设置第1张表及表别名
$table2 = ['tp5_dept'=>'b']; //设置第2张表及表别名
$field1 = ['id'=>'编号','name' => '姓名','salary' => '工资']; //设置第1张表字段别名
$field2 = ['dept_name' => '部门']; //设置第2张表字段别名
$on = 'a.dept = b.id'; //设置2张表连接条件
$type = 'LEFT'; //设置连接类型为左连接
//2.设置查询条件(数组方式进行批量设置)
$where = [];
$where['age'] = ['>=',40];
$where['salary'] = ['<=',8000];
//3.设置排序条件
$order = ['salary'=>'desc'];
//4.设置输出数量
$num = 3;
//1.执行多表视图查询
$result = Db::view($table1,$field1) //设置第1张表的表名与字段名
-> view($table2,$field2,$on,$type) //设置第1张表的表名与字段名,连接条件和连接类型
-> where($where) //设置查询条件
-> order($order) //设置结果排序条件
-> limit($num) // 设置输出记录数量
-> select(); //获取结果集
//4.输出结果
dump($result);
}
}查询结果:array(3) {
[0] => array(4) {
["编号"] => int(1027)
["姓名"] => string(9) "程序员"
["工资"] => float(5160)
["部门"] => string(9) "开发部"
}
[1] => array(4) {
["编号"] => int(1004)
["姓名"] => string(9) "小龙女"
["工资"] => float(2490)
["部门"] => string(9) "市场部"
}
[2] => array(4) {
["编号"] => int(1024)
["姓名"] => string(9) "鲁大师"
["工资"] => float(300)
["部门"] => string(9) "市场部"
}
}对应的SQL语句:SELECT a.id AS 编号,a.name AS 姓名,a.salary AS 工资,b.dept_name AS 部门
FROM `tp5_staff` `a` LEFT JOIN `tp5_dept` `b` ON `a`.`dept`=`b`.`id`
WHERE `age` >= 40 AND `salary` <= 8000
ORDER BY `salary` desc LIMIT 3
5、总结:view视图查询提供了一种不用join方法进行多表查询的另一种形式